diff options
author | Chris Michael <cp.michael@samsung.com> | 2015-06-02 09:05:26 -0400 |
---|---|---|
committer | Chris Michael <cp.michael@samsung.com> | 2015-06-05 10:00:44 -0400 |
commit | 58dbb63ba4bbc235477793b016ba31d2bf17d1fb (patch) | |
tree | a8ca151bf5871043ebe10d9cc66054865c84bfac | |
parent | 3f4c569341ab501b188f49c273bb961e0f1b75ee (diff) |
evas-gl-drm: Remove old engine code
Signed-off-by: Chris Michael <cp.michael@samsung.com>
-rw-r--r-- | src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h | 44 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_drm/evas_drm.c | 347 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_drm/evas_drm_main.c | 636 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_drm/evas_engine.h | 191 |
4 files changed, 0 insertions, 1218 deletions
diff --git a/src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h b/src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h deleted file mode 100644 index 92069b61e0..0000000000 --- a/src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | #ifndef _EVAS_ENGINE_GL_DRM_H | ||
2 | # define _EVAS_ENGINE_GL_DRM_H | ||
3 | |||
4 | # include <gbm.h> | ||
5 | # include <Ecore_Drm.h> | ||
6 | |||
7 | typedef struct _Evas_Engine_Info_GL_Drm Evas_Engine_Info_GL_Drm; | ||
8 | |||
9 | struct _Evas_Engine_Info_GL_Drm | ||
10 | { | ||
11 | /* PRIVATE - don't mess with this baby or evas will poke its tongue out | ||
12 | * at you and make nasty noises */ | ||
13 | Evas_Engine_Info magic; | ||
14 | |||
15 | /* engine specific data & parameters it needs to set up */ | ||
16 | struct | ||
17 | { | ||
18 | struct gbm_device *gbm; | ||
19 | struct gbm_surface *surface; | ||
20 | uint32_t format; | ||
21 | uint32_t flags; | ||
22 | int depth, screen, rotation; | ||
23 | unsigned char destination_alpha : 1; | ||
24 | int fd; | ||
25 | int output, plane; | ||
26 | Ecore_Drm_Device *dev; | ||
27 | } info; | ||
28 | |||
29 | struct | ||
30 | { | ||
31 | void (*pre_swap) (void *data, Evas *evas); | ||
32 | void (*post_swap) (void *data, Evas *evas); | ||
33 | void *data; | ||
34 | } callback; | ||
35 | |||
36 | /* non-blocking or blocking mode */ | ||
37 | Evas_Engine_Render_Mode render_mode; | ||
38 | |||
39 | unsigned char vsync : 1; | ||
40 | unsigned char indirect : 1; | ||
41 | unsigned char swap_mode : 4; | ||
42 | }; | ||
43 | |||
44 | #endif | ||
diff --git a/src/modules/evas/engines/gl_drm/evas_drm.c b/src/modules/evas/engines/gl_drm/evas_drm.c deleted file mode 100644 index c049fb9629..0000000000 --- a/src/modules/evas/engines/gl_drm/evas_drm.c +++ /dev/null | |||
@@ -1,347 +0,0 @@ | |||
1 | #include "evas_engine.h" | ||
2 | #include <sys/mman.h> | ||
3 | |||
4 | static void | ||
5 | _evas_drm_fb_destroy_callback(struct gbm_bo *bo, void *data) | ||
6 | { | ||
7 | Buffer *buffer = data; | ||
8 | struct gbm_device *gbm = gbm_bo_get_device(bo); | ||
9 | |||
10 | if (buffer->fb) | ||
11 | drmModeRmFB(gbm_device_get_fd(gbm), buffer->fb); | ||
12 | } | ||
13 | |||
14 | static unsigned int | ||
15 | _evas_drm_crtc_buffer_get(int fd, int crtc_id) | ||
16 | { | ||
17 | drmModeCrtc *crtc; | ||
18 | unsigned int id; | ||
19 | |||
20 | if (!(crtc = drmModeGetCrtc(fd, crtc_id))) return 0; | ||
21 | id = crtc->buffer_id; | ||
22 | drmModeFreeCrtc(crtc); | ||
23 | return id; | ||
24 | } | ||
25 | |||
26 | static void | ||
27 | _evas_drm_outbuf_page_flip(int fd EINA_UNUSED, unsigned int seq EINA_UNUSED, unsigned int tv_sec EINA_UNUSED, unsigned int tv_usec EINA_UNUSED, void *data) | ||
28 | { | ||
29 | Outbuf *ob; | ||
30 | Buffer *buff; | ||
31 | |||
32 | /* get the output buffer from data */ | ||
33 | if (!(ob = data)) return; | ||
34 | |||
35 | buff = &(ob->priv.buffer[ob->priv.curr]); | ||
36 | gbm_surface_release_buffer(ob->surface, buff->bo); | ||
37 | |||
38 | ob->priv.pending_flip = EINA_FALSE; | ||
39 | ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num; | ||
40 | } | ||
41 | |||
42 | static Eina_Bool | ||
43 | _evas_drm_outbuf_planes_setup(Outbuf *ob, drmModePlaneResPtr pres) | ||
44 | { | ||
45 | drmModePlanePtr dplane; | ||
46 | Plane *oplane; | ||
47 | unsigned int p = 0; | ||
48 | unsigned int f = 0; | ||
49 | |||
50 | for (p = 0; p < pres->count_planes; p++) | ||
51 | { | ||
52 | /* try to get this plane */ | ||
53 | if (!(dplane = drmModeGetPlane(ob->priv.fd, pres->planes[p]))) | ||
54 | continue; | ||
55 | |||
56 | /* try to allocate space for our plane */ | ||
57 | if (!(oplane = | ||
58 | malloc(sizeof(Plane) + | ||
59 | ((sizeof(unsigned int)) * dplane->count_formats)))) | ||
60 | { | ||
61 | drmModeFreePlane(dplane); | ||
62 | continue; | ||
63 | } | ||
64 | |||
65 | oplane->crtcs = dplane->possible_crtcs; | ||
66 | oplane->id = dplane->plane_id; | ||
67 | oplane->num_formats = dplane->count_formats; | ||
68 | memcpy(oplane->formats, dplane->formats, | ||
69 | dplane->count_formats * sizeof(dplane->formats[0])); | ||
70 | |||
71 | DBG("Plane %d, %d %d", p, dplane->x, dplane->y); | ||
72 | DBG("\tFB: %d", dplane->fb_id); | ||
73 | DBG("\tCrtc: %d, %d %d", dplane->crtc_id, | ||
74 | dplane->crtc_x, dplane->crtc_y); | ||
75 | |||
76 | DBG("\tSupported Formats"); | ||
77 | for (f = 0; f < dplane->count_formats; f++) | ||
78 | { | ||
79 | DBG("\t\t%C%C%C%C", (dplane->formats[f] & 0xFF), | ||
80 | ((dplane->formats[f] >> 8) & 0xFF), | ||
81 | ((dplane->formats[f] >> 16) & 0xFF), | ||
82 | ((dplane->formats[f] >> 24) & 0xFF)); | ||
83 | } | ||
84 | |||
85 | /* free this plane */ | ||
86 | drmModeFreePlane(dplane); | ||
87 | |||
88 | /* append this plane */ | ||
89 | ob->priv.planes = eina_list_append(ob->priv.planes, oplane); | ||
90 | } | ||
91 | |||
92 | if (eina_list_count(ob->priv.planes) < 1) return EINA_FALSE; | ||
93 | return EINA_TRUE; | ||
94 | } | ||
95 | |||
96 | Eina_Bool | ||
97 | evas_drm_gbm_init(Evas_Engine_Info_GL_Drm *info, int w, int h) | ||
98 | { | ||
99 | if (!info) return EINA_FALSE; | ||
100 | if (info->info.fd < 0) return EINA_FALSE; | ||
101 | |||
102 | if (!(info->info.gbm = gbm_create_device(info->info.fd))) | ||
103 | return EINA_FALSE; | ||
104 | |||
105 | if (!(info->info.surface = | ||
106 | gbm_surface_create(info->info.gbm, w, h, | ||
107 | info->info.format, info->info.flags))) | ||
108 | { | ||
109 | gbm_device_destroy(info->info.gbm); | ||
110 | info->info.gbm = NULL; | ||
111 | return EINA_FALSE; | ||
112 | } | ||
113 | |||
114 | return EINA_TRUE; | ||
115 | } | ||
116 | |||
117 | Eina_Bool | ||
118 | evas_drm_gbm_shutdown(Evas_Engine_Info_GL_Drm *info) | ||
119 | { | ||
120 | if (!info) return EINA_TRUE; | ||
121 | |||
122 | if (info->info.surface) | ||
123 | { | ||
124 | gbm_surface_destroy(info->info.surface); | ||
125 | info->info.surface = NULL; | ||
126 | } | ||
127 | if (info->info.gbm) | ||
128 | { | ||
129 | gbm_device_destroy(info->info.gbm); | ||
130 | info->info.gbm = NULL; | ||
131 | } | ||
132 | |||
133 | return EINA_TRUE; | ||
134 | } | ||
135 | |||
136 | Eina_Bool | ||
137 | evas_drm_outbuf_setup(Outbuf *ob) | ||
138 | { | ||
139 | drmModeRes *res; | ||
140 | drmModeConnector *conn; | ||
141 | drmModePlaneResPtr pres; | ||
142 | drmModeEncoder *enc; | ||
143 | drmModeModeInfo crtc_mode; | ||
144 | int i = 0; | ||
145 | |||
146 | /* check for valid Output buffer */ | ||
147 | if ((!ob) || (ob->priv.fd < 0)) return EINA_FALSE; | ||
148 | |||
149 | /* setup drmHandleEvent context */ | ||
150 | memset(&ob->priv.ctx, 0, sizeof(ob->priv.ctx)); | ||
151 | ob->priv.ctx.version = DRM_EVENT_CONTEXT_VERSION; | ||
152 | ob->priv.ctx.page_flip_handler = _evas_drm_outbuf_page_flip; | ||
153 | |||
154 | /* try to get drm resources */ | ||
155 | if (!(res = drmModeGetResources(ob->priv.fd))) | ||
156 | { | ||
157 | CRI("Could not get drm resources: %m"); | ||
158 | return EINA_FALSE; | ||
159 | } | ||
160 | |||
161 | /* loop the connectors */ | ||
162 | for (; i < res->count_connectors; ++i) | ||
163 | { | ||
164 | int crtc_id = -1; | ||
165 | int m = 0; | ||
166 | |||
167 | /* try to get this connector */ | ||
168 | if (!(conn = drmModeGetConnector(ob->priv.fd, res->connectors[i]))) | ||
169 | { | ||
170 | WRN("Could not get drm connector %d: %m", i); | ||
171 | continue; | ||
172 | } | ||
173 | |||
174 | /* make sure this connector is actually connected */ | ||
175 | if (conn->connection != DRM_MODE_CONNECTED) | ||
176 | { | ||
177 | /* free connector resources */ | ||
178 | drmModeFreeConnector(conn); | ||
179 | continue; | ||
180 | } | ||
181 | |||
182 | /* make sure it has modes */ | ||
183 | if (conn->count_modes == 0) | ||
184 | { | ||
185 | /* free connector resources */ | ||
186 | drmModeFreeConnector(conn); | ||
187 | continue; | ||
188 | } | ||
189 | |||
190 | /* record the connector id */ | ||
191 | ob->priv.conn = conn->connector_id; | ||
192 | |||
193 | if ((enc = drmModeGetEncoder(ob->priv.fd, conn->encoder_id))) | ||
194 | { | ||
195 | drmModeCrtc *crtc; | ||
196 | |||
197 | if ((crtc = drmModeGetCrtc(ob->priv.fd, enc->crtc_id))) | ||
198 | { | ||
199 | crtc_id = enc->crtc_id; | ||
200 | if (crtc->mode_valid) crtc_mode = crtc->mode; | ||
201 | drmModeFreeCrtc(crtc); | ||
202 | } | ||
203 | |||
204 | drmModeFreeEncoder(enc); | ||
205 | } | ||
206 | |||
207 | /* record the crtc id */ | ||
208 | ob->priv.crtc = crtc_id; | ||
209 | |||
210 | /* get the current framebuffer */ | ||
211 | ob->priv.fb = _evas_drm_crtc_buffer_get(ob->priv.fd, crtc_id); | ||
212 | |||
213 | memset(&ob->priv.mode, 0, sizeof(ob->priv.mode)); | ||
214 | |||
215 | for (m = 0; m < conn->count_modes; m++) | ||
216 | { | ||
217 | DBG("Output Available Mode: %d: %d %d %d", ob->priv.conn, | ||
218 | conn->modes[m].hdisplay, conn->modes[m].vdisplay, | ||
219 | conn->modes[m].vrefresh); | ||
220 | if (!memcmp(&crtc_mode, &conn->modes[m], sizeof(crtc_mode))) | ||
221 | { | ||
222 | /* record the current mode */ | ||
223 | memcpy(&ob->priv.mode, &conn->modes[m], sizeof(ob->priv.mode)); | ||
224 | break; | ||
225 | } | ||
226 | |||
227 | } | ||
228 | |||
229 | if ((!ob->priv.mode.hdisplay) && (crtc_mode.clock != 0)) | ||
230 | memcpy(&ob->priv.mode, &crtc_mode, sizeof(ob->priv.mode)); | ||
231 | |||
232 | DBG("Output Current Mode: %d: %d %d", ob->priv.conn, | ||
233 | ob->priv.mode.hdisplay, ob->priv.mode.vdisplay); | ||
234 | |||
235 | if ((ob->priv.mode.hdisplay != conn->modes[0].hdisplay) || | ||
236 | (ob->priv.mode.vdisplay != conn->modes[0].vdisplay)) | ||
237 | { | ||
238 | /* set new crtc mode */ | ||
239 | drmModeSetCrtc(ob->priv.fd, ob->priv.crtc, ob->priv.fb, 0, 0, | ||
240 | &ob->priv.conn, 1, &ob->priv.mode); | ||
241 | } | ||
242 | |||
243 | /* free connector resources */ | ||
244 | drmModeFreeConnector(conn); | ||
245 | |||
246 | break; | ||
247 | } | ||
248 | |||
249 | /* get any plane resource from the card */ | ||
250 | pres = drmModeGetPlaneResources(ob->priv.fd); | ||
251 | |||
252 | /* if we have at least one plane, set it up */ | ||
253 | if (pres->count_planes > 0) | ||
254 | { | ||
255 | if (!_evas_drm_outbuf_planes_setup(ob, pres)) | ||
256 | WRN("Could not setup hardware planes"); | ||
257 | } | ||
258 | |||
259 | /* free plane resources */ | ||
260 | drmModeFreePlaneResources(pres); | ||
261 | |||
262 | /* free drm resources */ | ||
263 | drmModeFreeResources(res); | ||
264 | |||
265 | return EINA_TRUE; | ||
266 | } | ||
267 | |||
268 | void | ||
269 | evas_drm_outbuf_framebuffer_set(Outbuf *ob, Buffer *buffer) | ||
270 | { | ||
271 | int ret; | ||
272 | uint32_t handles[4], pitches[4], offsets[4]; | ||
273 | uint32_t width, height; | ||
274 | uint32_t format; | ||
275 | |||
276 | /* validate params */ | ||
277 | if ((!ob) || (!buffer)) return; | ||
278 | |||
279 | if (buffer->valid) return; | ||
280 | |||
281 | width = gbm_bo_get_width(buffer->bo); | ||
282 | height = gbm_bo_get_height(buffer->bo); | ||
283 | buffer->stride = gbm_bo_get_stride(buffer->bo); | ||
284 | buffer->handle = gbm_bo_get_handle(buffer->bo).u32; | ||
285 | buffer->size = buffer->stride * height; | ||
286 | format = gbm_bo_get_format(buffer->bo); | ||
287 | |||
288 | handles[0] = buffer->handle; | ||
289 | pitches[0] = buffer->stride; | ||
290 | offsets[0] = 0; | ||
291 | |||
292 | ret = drmModeAddFB2(ob->priv.fd, width, height, format, handles, | ||
293 | pitches, offsets, &(buffer->fb), 0); | ||
294 | if (ret) | ||
295 | { | ||
296 | ret = drmModeAddFB(ob->priv.fd, width, height, 24, 32, | ||
297 | buffer->stride, buffer->handle, &(buffer->fb)); | ||
298 | } | ||
299 | if (ret) ERR("Failed to AddFB: %m"); | ||
300 | |||
301 | ret = drmModeSetCrtc(ob->priv.fd, ob->priv.crtc, buffer->fb, 0, 0, | ||
302 | &ob->priv.conn, 1, &ob->priv.mode); | ||
303 | if (ret) ERR("Failed to set crtc: %m"); | ||
304 | |||
305 | gbm_bo_set_user_data(buffer->bo, buffer, _evas_drm_fb_destroy_callback); | ||
306 | |||
307 | buffer->valid = EINA_TRUE; | ||
308 | } | ||
309 | |||
310 | Eina_Bool | ||
311 | evas_drm_framebuffer_send(Outbuf *ob, Buffer *buffer) | ||
312 | { | ||
313 | /* check for valid Output buffer */ | ||
314 | if ((!ob) || (ob->priv.fd < 0)) return EINA_FALSE; | ||
315 | |||
316 | /* check for valid buffer */ | ||
317 | if (!buffer) return EINA_FALSE; | ||
318 | |||
319 | if (ob->vsync) | ||
320 | { | ||
321 | if (drmModePageFlip(ob->priv.fd, ob->priv.crtc, | ||
322 | buffer->fb, DRM_MODE_PAGE_FLIP_EVENT, ob) < 0) | ||
323 | { | ||
324 | ERR("Cannot flip crtc for connector %u: %m", ob->priv.conn); | ||
325 | return EINA_FALSE; | ||
326 | } | ||
327 | |||
328 | ob->priv.pending_flip = EINA_TRUE; | ||
329 | |||
330 | while (ob->priv.pending_flip) | ||
331 | drmHandleEvent(ob->priv.fd, &ob->priv.ctx); | ||
332 | } | ||
333 | else | ||
334 | { | ||
335 | /* NB: We don't actually need to do this if we are not vsync | ||
336 | * because we are drawing directly to the buffer anyway. | ||
337 | * If we enable the sending of buffer to crtc, it causes vsync */ | ||
338 | |||
339 | /* send this buffer to the crtc */ | ||
340 | /* evas_drm_outbuf_framebuffer_set(ob, buffer); */ | ||
341 | |||
342 | /* increment buffer we are using */ | ||
343 | ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num; | ||
344 | } | ||
345 | |||
346 | return EINA_TRUE; | ||
347 | } | ||
diff --git a/src/modules/evas/engines/gl_drm/evas_drm_main.c b/src/modules/evas/engines/gl_drm/evas_drm_main.c deleted file mode 100644 index 9918673974..0000000000 --- a/src/modules/evas/engines/gl_drm/evas_drm_main.c +++ /dev/null | |||
@@ -1,636 +0,0 @@ | |||
1 | #include "evas_engine.h" | ||
2 | |||
3 | /* local variables */ | ||
4 | static Outbuf *_evas_gl_drm_window = NULL; | ||
5 | static EGLContext context = EGL_NO_CONTEXT; | ||
6 | static int win_count = 0; | ||
7 | |||
8 | /* local function prototypes */ | ||
9 | static void _outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count); | ||
10 | static void _outbuf_flush_famebuffer(Outbuf *ob); | ||
11 | |||
12 | /* local functions */ | ||
13 | static void | ||
14 | _outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects EINA_UNUSED, unsigned int count EINA_UNUSED) | ||
15 | { | ||
16 | Buffer *buff; | ||
17 | |||
18 | buff = &(ob->priv.buffer[ob->priv.curr]); | ||
19 | |||
20 | buff->bo = gbm_surface_lock_front_buffer(ob->surface); | ||
21 | |||
22 | /* if this buffer is not valid, we need to set it */ | ||
23 | if (!buff->valid) evas_drm_outbuf_framebuffer_set(ob, buff); | ||
24 | |||
25 | /* send this buffer to the crtc */ | ||
26 | evas_drm_framebuffer_send(ob, buff); | ||
27 | } | ||
28 | |||
29 | static void | ||
30 | _outbuf_flush_famebuffer(Outbuf *ob) | ||
31 | { | ||
32 | Eina_Rectangle *rects = NULL; | ||
33 | unsigned int n = 0; | ||
34 | //TODO: add region flush routine for SwapBuffersWithDamage | ||
35 | |||
36 | /* force a buffer swap */ | ||
37 | _outbuf_buffer_swap(ob, rects, n); | ||
38 | } | ||
39 | |||
40 | Outbuf * | ||
41 | eng_window_new(Evas_Engine_Info_GL_Drm *info, Evas *e, struct gbm_device *gbm, struct gbm_surface *surface, int screen, int depth, int w, int h, int indirect EINA_UNUSED, int alpha, int rot, Render_Engine_Swap_Mode swap_mode) | ||
42 | { | ||
43 | Outbuf *gw; | ||
44 | int context_attrs[3]; | ||
45 | int config_attrs[40]; | ||
46 | int major_version, minor_version; | ||
47 | int num_config, n = 0; | ||
48 | const GLubyte *vendor, *renderer, *version, *glslversion; | ||
49 | Eina_Bool blacklist = EINA_FALSE; | ||
50 | char *num; | ||
51 | |||
52 | /* try to allocate space for outbuf */ | ||
53 | gw = calloc(1, sizeof(Outbuf)); | ||
54 | if (!gw) return NULL; | ||
55 | |||
56 | /* set properties of outbuf */ | ||
57 | win_count++; | ||
58 | gw->gbm = gbm; | ||
59 | gw->surface = surface; | ||
60 | gw->screen = screen; | ||
61 | gw->depth = depth; | ||
62 | gw->w = w; | ||
63 | gw->h = h; | ||
64 | gw->alpha = alpha; | ||
65 | gw->rot = rot; | ||
66 | gw->swap_mode = swap_mode; | ||
67 | gw->info = info; | ||
68 | gw->evas = e; | ||
69 | |||
70 | /* setup drm outbuf */ | ||
71 | /* set drm card fd */ | ||
72 | gw->priv.fd = info->info.fd; | ||
73 | /* try to setup the drm card for this outbuf */ | ||
74 | if (!evas_drm_outbuf_setup(gw)) | ||
75 | { | ||
76 | ERR("Could not setup drm outbuf"); | ||
77 | free(gw); | ||
78 | return NULL; | ||
79 | } | ||
80 | |||
81 | if (gw->w < gw->priv.mode.hdisplay) gw->w = gw->priv.mode.hdisplay; | ||
82 | if (gw->h < gw->priv.mode.vdisplay) gw->h = gw->priv.mode.vdisplay; | ||
83 | |||
84 | info->info.output = gw->priv.fb; | ||
85 | // TODO: change vsync for drm egl | ||
86 | //gw->vsync = info->vsync; | ||
87 | |||
88 | gw->priv.num = NUM_BUFFERS; | ||
89 | /* check for buffer override */ | ||
90 | // TODO: change for gbm_bo related drm buffer number. | ||
91 | if ((num = getenv("EVAS_GL_DRM_BUFFERS"))) | ||
92 | { | ||
93 | gw->priv.num = atoi(num); | ||
94 | |||
95 | /* cap maximum # of buffers */ | ||
96 | if (gw->priv.num <= 0) gw->priv.num = 1; | ||
97 | else if (gw->priv.num > 3) gw->priv.num = 3; | ||
98 | } | ||
99 | /* end drm outbuf setup */ | ||
100 | |||
101 | /* setup gbm egl surface */ | ||
102 | context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION; | ||
103 | context_attrs[1] = 2; | ||
104 | context_attrs[2] = EGL_NONE; | ||
105 | |||
106 | config_attrs[n++] = EGL_SURFACE_TYPE; | ||
107 | config_attrs[n++] = EGL_WINDOW_BIT; | ||
108 | config_attrs[n++] = EGL_RED_SIZE; | ||
109 | config_attrs[n++] = 1; | ||
110 | config_attrs[n++] = EGL_GREEN_SIZE; | ||
111 | config_attrs[n++] = 1; | ||
112 | config_attrs[n++] = EGL_BLUE_SIZE; | ||
113 | config_attrs[n++] = 1; | ||
114 | config_attrs[n++] = EGL_ALPHA_SIZE; | ||
115 | if (gw->alpha) config_attrs[n++] = 1; | ||
116 | else config_attrs[n++] = 0; | ||
117 | config_attrs[n++] = EGL_RENDERABLE_TYPE; | ||
118 | config_attrs[n++] = EGL_OPENGL_ES2_BIT; | ||
119 | config_attrs[n++] = EGL_NONE; | ||
120 | |||
121 | #ifdef GL_DRM_DBG | ||
122 | DBG("GBM DEVICE: %x", (unsigned int)gbm); | ||
123 | #endif | ||
124 | |||
125 | gw->egl_disp = eglGetDisplay((EGLNativeDisplayType)(gw->gbm)); | ||
126 | if (gw->egl_disp == EGL_NO_DISPLAY) | ||
127 | { | ||
128 | ERR("eglGetDisplay() fail. code=%#x", eglGetError()); | ||
129 | eng_window_free(gw); | ||
130 | return NULL; | ||
131 | } | ||
132 | if (!eglInitialize(gw->egl_disp, &major_version, &minor_version)) | ||
133 | { | ||
134 | ERR("eglInitialize() fail. code=%#x", eglGetError()); | ||
135 | eng_window_free(gw); | ||
136 | return NULL; | ||
137 | } | ||
138 | eglBindAPI(EGL_OPENGL_ES_API); | ||
139 | if (eglGetError() != EGL_SUCCESS) | ||
140 | { | ||
141 | ERR("eglBindAPI() fail. code=%#x", eglGetError()); | ||
142 | eng_window_free(gw); | ||
143 | return NULL; | ||
144 | } | ||
145 | |||
146 | num_config = 0; | ||
147 | if (!eglChooseConfig(gw->egl_disp, config_attrs, &gw->egl_config, | ||
148 | 1, &num_config) || (num_config != 1)) | ||
149 | { | ||
150 | ERR("eglChooseConfig() fail. code=%#x", eglGetError()); | ||
151 | eng_window_free(gw); | ||
152 | return NULL; | ||
153 | } | ||
154 | |||
155 | gw->egl_surface[0] = | ||
156 | eglCreateWindowSurface(gw->egl_disp, gw->egl_config, | ||
157 | (EGLNativeWindowType)gw->surface, NULL); | ||
158 | if (gw->egl_surface[0] == EGL_NO_SURFACE) | ||
159 | { | ||
160 | ERR("eglCreateWindowSurface() fail for %p. code=%#x", | ||
161 | gw->surface, eglGetError()); | ||
162 | eng_window_free(gw); | ||
163 | return NULL; | ||
164 | } | ||
165 | |||
166 | gw->egl_context[0] = | ||
167 | eglCreateContext(gw->egl_disp, gw->egl_config, context, context_attrs); | ||
168 | if (gw->egl_context[0] == EGL_NO_CONTEXT) | ||
169 | { | ||
170 | ERR("eglCreateContext() fail. code=%#x", eglGetError()); | ||
171 | eng_window_free(gw); | ||
172 | return NULL; | ||
173 | } | ||
174 | |||
175 | if (context == EGL_NO_CONTEXT) context = gw->egl_context[0]; | ||
176 | |||
177 | if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], | ||
178 | gw->egl_surface[0], gw->egl_context[0]) == EGL_FALSE) | ||
179 | { | ||
180 | ERR("eglMakeCurrent() fail. code=%#x", eglGetError()); | ||
181 | eng_window_free(gw); | ||
182 | return NULL; | ||
183 | } | ||
184 | |||
185 | vendor = glGetString(GL_VENDOR); | ||
186 | renderer = glGetString(GL_RENDERER); | ||
187 | version = glGetString(GL_VERSION); | ||
188 | glslversion = glGetString(GL_SHADING_LANGUAGE_VERSION); | ||
189 | if (!vendor) vendor = (unsigned char *)"-UNKNOWN-"; | ||
190 | if (!renderer) renderer = (unsigned char *)"-UNKNOWN-"; | ||
191 | if (!version) version = (unsigned char *)"-UNKNOWN-"; | ||
192 | if (!glslversion) glslversion = (unsigned char *)"-UNKNOWN-"; | ||
193 | if (getenv("EVAS_GL_INFO")) | ||
194 | { | ||
195 | fprintf(stderr, "vendor : %s\n", vendor); | ||
196 | fprintf(stderr, "renderer: %s\n", renderer); | ||
197 | fprintf(stderr, "version : %s\n", version); | ||
198 | fprintf(stderr, "glsl ver: %s\n", glslversion); | ||
199 | } | ||
200 | |||
201 | if (strstr((const char *)vendor, "Mesa Project")) | ||
202 | { | ||
203 | if (strstr((const char *)renderer, "Software Rasterizer")) | ||
204 | blacklist = EINA_TRUE; | ||
205 | } | ||
206 | if (strstr((const char *)renderer, "softpipe")) | ||
207 | blacklist = EINA_TRUE; | ||
208 | if (strstr((const char *)renderer, "llvmpipe")) | ||
209 | blacklist = EINA_TRUE; | ||
210 | if ((blacklist) && (!getenv("EVAS_GL_NO_BLACKLIST"))) | ||
211 | { | ||
212 | ERR("OpenGL Driver blacklisted:"); | ||
213 | ERR("Vendor: %s", (const char *)vendor); | ||
214 | ERR("Renderer: %s", (const char *)renderer); | ||
215 | ERR("Version: %s", (const char *)version); | ||
216 | eng_window_free(gw); | ||
217 | return NULL; | ||
218 | } | ||
219 | |||
220 | gw->gl_context = glsym_evas_gl_common_context_new(); | ||
221 | if (!gw->gl_context) | ||
222 | { | ||
223 | eng_window_free(gw); | ||
224 | return NULL; | ||
225 | } | ||
226 | |||
227 | #ifdef GL_GLES | ||
228 | gw->gl_context->egldisp = gw->egl_disp; | ||
229 | gw->gl_context->eglctxt = gw->egl_context[0]; | ||
230 | #endif | ||
231 | |||
232 | eng_window_use(gw); | ||
233 | glsym_evas_gl_common_context_resize(gw->gl_context, w, h, rot); | ||
234 | |||
235 | gw->surf = EINA_TRUE; | ||
236 | |||
237 | return gw; | ||
238 | } | ||
239 | |||
240 | void | ||
241 | eng_window_free(Outbuf *gw) | ||
242 | { | ||
243 | int ref = 0; | ||
244 | |||
245 | win_count--; | ||
246 | eng_window_use(gw); | ||
247 | |||
248 | if (gw == _evas_gl_drm_window) _evas_gl_drm_window = NULL; | ||
249 | |||
250 | if (gw->gl_context) | ||
251 | { | ||
252 | ref = gw->gl_context->references - 1; | ||
253 | glsym_evas_gl_common_context_free(gw->gl_context); | ||
254 | } | ||
255 | |||
256 | eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | ||
257 | |||
258 | if (gw->egl_context[0] != context) | ||
259 | eglDestroyContext(gw->egl_disp, gw->egl_context[0]); | ||
260 | |||
261 | if (gw->egl_surface[0] != EGL_NO_SURFACE) | ||
262 | eglDestroySurface(gw->egl_disp, gw->egl_surface[0]); | ||
263 | |||
264 | //TODO: consider gbm_surface destroy or not. | ||
265 | #if 0 | ||
266 | if (gw->surface) | ||
267 | { | ||
268 | gbm_surface_destroy(gw->surface); | ||
269 | gw->info->info.surface = NULL; | ||
270 | } | ||
271 | #endif | ||
272 | |||
273 | if (ref == 0) | ||
274 | { | ||
275 | if (context) eglDestroyContext(gw->egl_disp, context); | ||
276 | eglTerminate(gw->egl_disp); | ||
277 | eglReleaseThread(); | ||
278 | context = EGL_NO_CONTEXT; | ||
279 | } | ||
280 | free(gw); | ||
281 | } | ||
282 | |||
283 | Eina_Bool | ||
284 | eng_window_make_current(void *data, void *doit) | ||
285 | { | ||
286 | Outbuf *gw; | ||
287 | |||
288 | if (!(gw = data)) return EINA_FALSE; | ||
289 | |||
290 | if (doit) | ||
291 | { | ||
292 | if (!eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], | ||
293 | gw->egl_surface[0], gw->egl_context[0])) | ||
294 | return EINA_FALSE; | ||
295 | } | ||
296 | else | ||
297 | { | ||
298 | if (!eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, | ||
299 | EGL_NO_SURFACE, EGL_NO_CONTEXT)) | ||
300 | return EINA_FALSE; | ||
301 | } | ||
302 | |||
303 | return EINA_TRUE; | ||
304 | } | ||
305 | |||
306 | void | ||
307 | eng_window_use(Outbuf *gw) | ||
308 | { | ||
309 | Eina_Bool force = EINA_FALSE; | ||
310 | |||
311 | glsym_evas_gl_preload_render_lock(eng_window_make_current, gw); | ||
312 | |||
313 | if (_evas_gl_drm_window) | ||
314 | { | ||
315 | if (eglGetCurrentContext() != _evas_gl_drm_window->egl_context[0]) | ||
316 | force = EINA_TRUE; | ||
317 | } | ||
318 | |||
319 | if ((_evas_gl_drm_window != gw) || (force)) | ||
320 | { | ||
321 | if (_evas_gl_drm_window) | ||
322 | { | ||
323 | glsym_evas_gl_common_context_use(_evas_gl_drm_window->gl_context); | ||
324 | glsym_evas_gl_common_context_flush(_evas_gl_drm_window->gl_context); | ||
325 | } | ||
326 | |||
327 | _evas_gl_drm_window = gw; | ||
328 | |||
329 | if (gw) | ||
330 | { | ||
331 | if (gw->egl_surface[0] != EGL_NO_SURFACE) | ||
332 | { | ||
333 | if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], | ||
334 | gw->egl_surface[0], | ||
335 | gw->egl_context[0]) == EGL_FALSE) | ||
336 | ERR("eglMakeCurrent() failed!"); | ||
337 | } | ||
338 | } | ||
339 | } | ||
340 | |||
341 | if (gw) glsym_evas_gl_common_context_use(gw->gl_context); | ||
342 | } | ||
343 | |||
344 | void | ||
345 | eng_window_unsurf(Outbuf *gw) | ||
346 | { | ||
347 | if (!gw->surf) return; | ||
348 | if (!getenv("EVAS_GL_WIN_RESURF")) return; | ||
349 | if (getenv("EVAS_GL_INFO")) printf("unsurf %p\n", gw); | ||
350 | |||
351 | if (_evas_gl_drm_window) | ||
352 | glsym_evas_gl_common_context_flush(_evas_gl_drm_window->gl_context); | ||
353 | if (_evas_gl_drm_window == gw) | ||
354 | { | ||
355 | eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, | ||
356 | EGL_NO_SURFACE, EGL_NO_CONTEXT); | ||
357 | if (gw->egl_surface[0] != EGL_NO_SURFACE) | ||
358 | eglDestroySurface(gw->egl_disp, gw->egl_surface[0]); | ||
359 | gw->egl_surface[0] = EGL_NO_SURFACE; | ||
360 | |||
361 | _evas_gl_drm_window = NULL; | ||
362 | } | ||
363 | |||
364 | gw->surf = EINA_FALSE; | ||
365 | } | ||
366 | |||
367 | void | ||
368 | eng_window_resurf(Outbuf *gw) | ||
369 | { | ||
370 | if (gw->surf) return; | ||
371 | if (getenv("EVAS_GL_INFO")) printf("resurf %p\n", gw); | ||
372 | |||
373 | gw->egl_surface[0] = | ||
374 | eglCreateWindowSurface(gw->egl_disp, gw->egl_config, | ||
375 | (EGLNativeWindowType)gw->surface, NULL); | ||
376 | |||
377 | if (gw->egl_surface[0] == EGL_NO_SURFACE) | ||
378 | { | ||
379 | ERR("eglCreateWindowSurface() fail for %p. code=%#x", | ||
380 | gw->surface, eglGetError()); | ||
381 | return; | ||
382 | } | ||
383 | |||
384 | if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], gw->egl_surface[0], | ||
385 | gw->egl_context[0]) == EGL_FALSE) | ||
386 | ERR("eglMakeCurrent() failed!"); | ||
387 | |||
388 | gw->surf = EINA_TRUE; | ||
389 | } | ||
390 | |||
391 | Context_3D * | ||
392 | eng_gl_context_new(Outbuf *gw) | ||
393 | { | ||
394 | Context_3D *ctx; | ||
395 | int context_attrs[3] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; | ||
396 | |||
397 | if (!gw) return NULL; | ||
398 | |||
399 | ctx = calloc(1, sizeof(Context_3D)); | ||
400 | if (!ctx) return NULL; | ||
401 | |||
402 | ctx->context = eglCreateContext(gw->egl_disp, gw->egl_config, | ||
403 | gw->egl_context[0], context_attrs); | ||
404 | |||
405 | if (!ctx->context) | ||
406 | { | ||
407 | ERR("EGL context creation failed."); | ||
408 | goto error; | ||
409 | } | ||
410 | |||
411 | ctx->display = gw->egl_disp; | ||
412 | ctx->surface = gw->egl_surface[0]; | ||
413 | |||
414 | return ctx; | ||
415 | |||
416 | error: | ||
417 | free(ctx); | ||
418 | return NULL; | ||
419 | } | ||
420 | |||
421 | void | ||
422 | eng_gl_context_free(Context_3D *ctx) | ||
423 | { | ||
424 | eglDestroyContext(ctx->display, ctx->context); | ||
425 | free(ctx); | ||
426 | } | ||
427 | |||
428 | void | ||
429 | eng_gl_context_use(Context_3D *ctx) | ||
430 | { | ||
431 | if (eglMakeCurrent(ctx->display, ctx->surface, | ||
432 | ctx->surface, ctx->context) == EGL_FALSE) | ||
433 | ERR("eglMakeCurrent() failed."); | ||
434 | } | ||
435 | |||
436 | void | ||
437 | eng_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth EINA_UNUSED) | ||
438 | { | ||
439 | ob->w = w; | ||
440 | ob->h = h; | ||
441 | ob->rot = rot; | ||
442 | eng_window_use(ob); | ||
443 | glsym_evas_gl_common_context_resize(ob->gl_context, w, h, rot); | ||
444 | |||
445 | //TODO: need drm gbm surface destroy & re-create.? | ||
446 | } | ||
447 | |||
448 | int | ||
449 | eng_outbuf_get_rot(Outbuf *ob) | ||
450 | { | ||
451 | return ob->rot; | ||
452 | } | ||
453 | |||
454 | Render_Engine_Swap_Mode | ||
455 | eng_outbuf_swap_mode(Outbuf *ob) | ||
456 | { | ||
457 | if (ob->swap_mode == MODE_AUTO && extn_have_buffer_age) | ||
458 | { | ||
459 | Render_Engine_Swap_Mode swap_mode; | ||
460 | |||
461 | EGLint age = 0; | ||
462 | |||
463 | if (!eglQuerySurface(ob->egl_disp, ob->egl_surface[0], | ||
464 | EGL_BUFFER_AGE_EXT, &age)) | ||
465 | age = 0; | ||
466 | |||
467 | if (age == 1) swap_mode = MODE_COPY; | ||
468 | else if (age == 2) swap_mode = MODE_DOUBLE; | ||
469 | else if (age == 3) swap_mode = MODE_TRIPLE; | ||
470 | else if (age == 4) swap_mode = MODE_QUADRUPLE; | ||
471 | else swap_mode = MODE_FULL; | ||
472 | if ((int)age != ob->prev_age) swap_mode = MODE_FULL; | ||
473 | ob->prev_age = age; | ||
474 | |||
475 | return swap_mode; | ||
476 | } | ||
477 | |||
478 | return ob->swap_mode; | ||
479 | } | ||
480 | |||
481 | Eina_Bool | ||
482 | eng_outbuf_region_first_rect(Outbuf *ob) | ||
483 | { | ||
484 | ob->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM; | ||
485 | |||
486 | glsym_evas_gl_preload_render_lock(eng_preload_make_current, ob); | ||
487 | eng_window_use(ob); | ||
488 | if (!_re_wincheck(ob)) return EINA_TRUE; | ||
489 | |||
490 | glsym_evas_gl_common_context_resize(ob->gl_context, ob->w, ob->h, ob->rot); | ||
491 | glsym_evas_gl_common_context_flush(ob->gl_context); | ||
492 | glsym_evas_gl_common_context_newframe(ob->gl_context); | ||
493 | |||
494 | return EINA_FALSE; | ||
495 | } | ||
496 | |||
497 | void * | ||
498 | eng_outbuf_new_region_for_update(Outbuf *ob, int x, int y, int w, int h, int *cx EINA_UNUSED, int *cy EINA_UNUSED, int *cw EINA_UNUSED, int *ch EINA_UNUSED) | ||
499 | { | ||
500 | if ((w == ob->w) && (h == ob->h)) | ||
501 | ob->gl_context->master_clip.enabled = EINA_FALSE; | ||
502 | else | ||
503 | { | ||
504 | ob->gl_context->master_clip.enabled = EINA_TRUE; | ||
505 | ob->gl_context->master_clip.x = x; | ||
506 | ob->gl_context->master_clip.y = y; | ||
507 | ob->gl_context->master_clip.w = w; | ||
508 | ob->gl_context->master_clip.h = h; | ||
509 | } | ||
510 | return ob->gl_context->def_surface; | ||
511 | } | ||
512 | |||
513 | void | ||
514 | eng_outbuf_push_updated_region(Outbuf *ob, RGBA_Image *update EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED) | ||
515 | { | ||
516 | /* Is it really necessary to flush per region ? Shouldn't we be able to | ||
517 | still do that for the full canvas when doing partial update */ | ||
518 | if (!_re_wincheck(ob)) return; | ||
519 | ob->draw.drew = EINA_TRUE; | ||
520 | glsym_evas_gl_common_context_flush(ob->gl_context); | ||
521 | } | ||
522 | |||
523 | void | ||
524 | eng_outbuf_push_free_region_for_update(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED) | ||
525 | { | ||
526 | /* Nothing to do here as we don't really create an image per area */ | ||
527 | } | ||
528 | |||
529 | void | ||
530 | eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode) | ||
531 | { | ||
532 | if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end; | ||
533 | |||
534 | if (!_re_wincheck(ob)) goto end; | ||
535 | if (!ob->draw.drew) goto end; | ||
536 | |||
537 | ob->draw.drew = EINA_FALSE; | ||
538 | eng_window_use(ob); | ||
539 | glsym_evas_gl_common_context_done(ob->gl_context); | ||
540 | |||
541 | if (!ob->vsync) | ||
542 | { | ||
543 | if (ob->info->vsync) eglSwapInterval(ob->egl_disp, 1); | ||
544 | else eglSwapInterval(ob->egl_disp, 0); | ||
545 | ob->vsync = 1; | ||
546 | } | ||
547 | |||
548 | if (ob->info->callback.pre_swap) | ||
549 | ob->info->callback.pre_swap(ob->info->callback.data, ob->evas); | ||
550 | |||
551 | // TODO: Check eglSwapBuffersWithDamage for gl_drm and apply | ||
552 | #if 0 | ||
553 | if ((glsym_eglSwapBuffersWithDamage) && (ob->swap_mode != MODE_FULL)) | ||
554 | |||
555 | { | ||
556 | EGLint num = 0, *result = NULL, i = 0; | ||
557 | Tilebuf_Rect *r; | ||
558 | |||
559 | // if partial swaps can be done use re->rects | ||
560 | num = eina_inlist_count(EINA_INLIST_GET(rects)); | ||
561 | if (num > 0) | ||
562 | { | ||
563 | result = alloca(sizeof(EGLint) * 4 * num); | ||
564 | EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r) | ||
565 | { | ||
566 | int gw, gh; | ||
567 | |||
568 | gw = ob->gl_context->w; | ||
569 | gh = ob->gl_context->h; | ||
570 | switch (ob->rot) | ||
571 | { | ||
572 | case 0: | ||
573 | result[i + 0] = r->x; | ||
574 | result[i + 1] = gh - (r->y + r->h); | ||
575 | result[i + 2] = r->w; | ||
576 | result[i + 3] = r->h; | ||
577 | break; | ||
578 | case 90: | ||
579 | result[i + 0] = r->y; | ||
580 | result[i + 1] = r->x; | ||
581 | result[i + 2] = r->h; | ||
582 | result[i + 3] = r->w; | ||
583 | break; | ||
584 | case 180: | ||
585 | result[i + 0] = gw - (r->x + r->w); | ||
586 | result[i + 1] = r->y; | ||
587 | result[i + 2] = r->w; | ||
588 | result[i + 3] = r->h; | ||
589 | break; | ||
590 | case 270: | ||
591 | result[i + 0] = gh - (r->y + r->h); | ||
592 | result[i + 1] = gw - (r->x + r->w); | ||
593 | result[i + 2] = r->h; | ||
594 | result[i + 3] = r->w; | ||
595 | break; | ||
596 | default: | ||
597 | result[i + 0] = r->x; | ||
598 | result[i + 1] = gh - (r->y + r->h); | ||
599 | result[i + 2] = r->w; | ||
600 | result[i + 3] = r->h; | ||
601 | break; | ||
602 | } | ||
603 | i += 4; | ||
604 | } | ||
605 | glsym_eglSwapBuffersWithDamage(ob->egl_disp, ob->egl_surface[0], | ||
606 | result, num); | ||
607 | } | ||
608 | } | ||
609 | else | ||
610 | #endif | ||
611 | eglSwapBuffers(ob->egl_disp, ob->egl_surface[0]); | ||
612 | |||
613 | if (ob->info->callback.post_swap) | ||
614 | ob->info->callback.post_swap(ob->info->callback.data, ob->evas); | ||
615 | |||
616 | //Flush GL Surface data to Framebuffer | ||
617 | _outbuf_flush_famebuffer(ob); | ||
618 | |||
619 | ob->frame_cnt++; | ||
620 | |||
621 | end: | ||
622 | //TODO: Need render unlock after drm page flip? | ||
623 | glsym_evas_gl_preload_render_unlock(eng_preload_make_current, ob); | ||
624 | } | ||
625 | |||
626 | Evas_Engine_GL_Context * | ||
627 | eng_outbuf_gl_context_get(Outbuf *ob) | ||
628 | { | ||
629 | return ob->gl_context; | ||
630 | } | ||
631 | |||
632 | void * | ||
633 | eng_outbuf_egl_display_get(Outbuf *ob) | ||
634 | { | ||
635 | return ob->egl_disp; | ||
636 | } | ||
diff --git a/src/modules/evas/engines/gl_drm/evas_engine.h b/src/modules/evas/engines/gl_drm/evas_engine.h deleted file mode 100644 index b97b0476fe..0000000000 --- a/src/modules/evas/engines/gl_drm/evas_engine.h +++ /dev/null | |||
@@ -1,191 +0,0 @@ | |||
1 | #ifndef EVAS_ENGINE_H | ||
2 | # define EVAS_ENGINE_H | ||
3 | |||
4 | #include "config.h" | ||
5 | #include "evas_common_private.h" | ||
6 | #include "evas_private.h" | ||
7 | #include "Evas.h" | ||
8 | #include "Evas_Engine_GL_Drm.h" | ||
9 | #include "evas_macros.h" | ||
10 | |||
11 | #define GL_GLEXT_PROTOTYPES | ||
12 | #include <EGL/egl.h> | ||
13 | #include <EGL/eglext.h> | ||
14 | #include <EGL/eglmesaext.h> | ||
15 | #include <GLES2/gl2.h> | ||
16 | #include <GLES2/gl2ext.h> | ||
17 | #include "../gl_generic/Evas_Engine_GL_Generic.h" | ||
18 | |||
19 | #include <xf86drm.h> | ||
20 | #include <xf86drmMode.h> | ||
21 | #include <drm_fourcc.h> | ||
22 | |||
23 | #include <signal.h> | ||
24 | #include <sys/ioctl.h> | ||
25 | #include <sys/types.h> | ||
26 | #include <unistd.h> | ||
27 | #include <fcntl.h> | ||
28 | |||
29 | extern int extn_have_buffer_age; | ||
30 | extern int _evas_engine_gl_drm_log_dom; | ||
31 | |||
32 | extern Evas_GL_Common_Context_New glsym_evas_gl_common_context_new; | ||
33 | extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_flush; | ||
34 | extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_free; | ||
35 | extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use; | ||
36 | extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_newframe; | ||
37 | extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_done; | ||
38 | extern Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize; | ||
39 | extern Evas_GL_Common_Buffer_Dump_Call glsym_evas_gl_common_buffer_dump; | ||
40 | extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock; | ||
41 | extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock; | ||
42 | |||
43 | /* define this to enable debug for the gl_drm engine */ | ||
44 | /* #define GL_DRM_DBG 0 */ | ||
45 | |||
46 | # ifdef ERR | ||
47 | # undef ERR | ||
48 | # endif | ||
49 | # define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_gl_drm_log_dom, __VA_ARGS__) | ||
50 | |||
51 | # ifdef DBG | ||
52 | # undef DBG | ||
53 | # endif | ||
54 | # define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_gl_drm_log_dom, __VA_ARGS__) | ||
55 | |||
56 | # ifdef INF | ||
57 | # undef INF | ||
58 | # endif | ||
59 | # define INF(...) EINA_LOG_DOM_INFO(_evas_engine_gl_drm_log_dom, __VA_ARGS__) | ||
60 | |||
61 | # ifdef WRN | ||
62 | # undef WRN | ||
63 | # endif | ||
64 | # define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_gl_drm_log_dom, __VA_ARGS__) | ||
65 | |||
66 | # ifdef CRI | ||
67 | # undef CRI | ||
68 | # endif | ||
69 | # define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_gl_drm_log_dom, __VA_ARGS__) | ||
70 | |||
71 | # define NUM_BUFFERS 2 | ||
72 | |||
73 | typedef struct _Buffer Buffer; | ||
74 | typedef struct _Plane Plane; | ||
75 | |||
76 | struct _Buffer | ||
77 | { | ||
78 | int stride; | ||
79 | int size; | ||
80 | int handle; | ||
81 | unsigned int fb; | ||
82 | struct gbm_bo *bo; //used for hardware framebuffers | ||
83 | Eina_Bool valid : 1; | ||
84 | }; | ||
85 | |||
86 | struct _Plane | ||
87 | { | ||
88 | unsigned int id; | ||
89 | unsigned int crtcs; | ||
90 | |||
91 | struct | ||
92 | { | ||
93 | unsigned int x, y; | ||
94 | unsigned int w, h; | ||
95 | } src, dst; | ||
96 | |||
97 | unsigned int num_formats; | ||
98 | unsigned int formats[]; | ||
99 | }; | ||
100 | |||
101 | struct _Outbuf | ||
102 | { | ||
103 | EGLContext egl_context[1]; | ||
104 | EGLSurface egl_surface[1]; | ||
105 | EGLConfig egl_config; | ||
106 | EGLDisplay egl_disp; | ||
107 | struct gbm_device *gbm; | ||
108 | struct gbm_surface *surface; | ||
109 | Evas *evas; | ||
110 | uint32_t format; | ||
111 | uint32_t flags; | ||
112 | Evas_Engine_GL_Context *gl_context; | ||
113 | Evas_Engine_Info_GL_Drm *info; | ||
114 | Render_Engine_Swap_Mode swap_mode; | ||
115 | int w, h; | ||
116 | int depth, rot, screen, alpha; | ||
117 | int prev_age; | ||
118 | int frame_cnt; | ||
119 | int vsync; | ||
120 | Eina_Bool lost_back : 1; | ||
121 | Eina_Bool surf : 1; | ||
122 | |||
123 | struct | ||
124 | { | ||
125 | Eina_Bool drew : 1; | ||
126 | } draw; | ||
127 | |||
128 | struct | ||
129 | { | ||
130 | int fd; | ||
131 | unsigned int conn, crtc, fb; | ||
132 | Buffer buffer[NUM_BUFFERS]; | ||
133 | int curr, num; | ||
134 | drmModeModeInfo mode; | ||
135 | drmEventContext ctx; | ||
136 | Eina_List *pending_writes; | ||
137 | Eina_List *planes; | ||
138 | Eina_Bool pending_flip : 1; | ||
139 | } priv; | ||
140 | }; | ||
141 | |||
142 | struct _Context_3D | ||
143 | { | ||
144 | EGLDisplay display; | ||
145 | EGLContext context; | ||
146 | EGLSurface surface; | ||
147 | }; | ||
148 | |||
149 | Outbuf *eng_window_new(Evas_Engine_Info_GL_Drm *info, Evas *e, struct gbm_device *gbm, struct gbm_surface *surface, int screen, int depth, int w, int h, int indirect, int alpha, int rot, Render_Engine_Swap_Mode swap_mode); | ||
150 | void eng_window_free(Outbuf *gw); | ||
151 | void eng_window_use(Outbuf *gw); | ||
152 | void eng_window_unsurf(Outbuf *gw); | ||
153 | void eng_window_resurf(Outbuf *gw); | ||
154 | |||
155 | void eng_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth); | ||
156 | int eng_outbuf_get_rot(Outbuf *ob); | ||
157 | Render_Engine_Swap_Mode eng_outbuf_swap_mode(Outbuf *ob); | ||
158 | Eina_Bool eng_outbuf_region_first_rect(Outbuf *ob); | ||
159 | void *eng_outbuf_new_region_for_update(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); | ||
160 | void eng_outbuf_push_free_region_for_update(Outbuf *ob, RGBA_Image *update); | ||
161 | void eng_outbuf_push_updated_region(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); | ||
162 | void eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); | ||
163 | Evas_Engine_GL_Context* eng_outbuf_gl_context_get(Outbuf *ob); | ||
164 | void *eng_outbuf_egl_display_get(Outbuf *ob); | ||
165 | |||
166 | void eng_gl_context_free(Context_3D *context); | ||
167 | void eng_gl_context_use(Context_3D *context); | ||
168 | |||
169 | Eina_Bool eng_preload_make_current(void *data, void *doit); | ||
170 | |||
171 | Context_3D *eng_gl_context_new(Outbuf *win); | ||
172 | |||
173 | static inline Eina_Bool | ||
174 | _re_wincheck(Outbuf *ob) | ||
175 | { | ||
176 | if (ob->surf) return EINA_TRUE; | ||
177 | eng_window_resurf(ob); | ||
178 | ob->lost_back = 1; | ||
179 | if (!ob->surf) | ||
180 | { | ||
181 | ERR("GL engine can't re-create window surface!"); | ||
182 | } | ||
183 | return EINA_FALSE; | ||
184 | } | ||
185 | |||
186 | Eina_Bool evas_drm_gbm_init(Evas_Engine_Info_GL_Drm *info, int w, int h); | ||
187 | Eina_Bool evas_drm_gbm_shutdown(Evas_Engine_Info_GL_Drm *info); | ||
188 | Eina_Bool evas_drm_outbuf_setup(Outbuf *ob); | ||
189 | void evas_drm_outbuf_framebuffer_set(Outbuf *ob, Buffer *buffer); | ||
190 | Eina_Bool evas_drm_framebuffer_send(Outbuf *ob, Buffer *buffer); | ||
191 | #endif | ||