diff options
author | Derek Foreman <derekf@osg.samsung.com> | 2017-05-12 14:41:03 -0500 |
---|---|---|
committer | Derek Foreman <derekf@osg.samsung.com> | 2017-05-12 17:51:34 -0500 |
commit | edcbff59b72ef8b26af99c1cb3c38f4ffb48282a (patch) | |
tree | 3715fc4cdd8906b55969edf4214fdc3f1e7da9d6 | |
parent | 69b941f018a5e289f4eb34adcfdc774c0d9a2409 (diff) | |
download | efl-edcbff59b72ef8b26af99c1cb3c38f4ffb48282a.tar.gz |
ecore_drm2: refcount fbs
Removes the previous "busy" flag, as now we might have an fb attached to
multiple outputs at once, and need to be careful to destroy them only
after they've been removed from all outputs.
Removed the old "busy_set" API which nothing used, and renames fb_destroy
to fb_discard to make it more clear that it's not immediately destroyed.
It's all beta api, so I can do this.
-rw-r--r-- | src/lib/ecore_drm2/Ecore_Drm2.h | 33 | ||||
-rw-r--r-- | src/lib/ecore_drm2/ecore_drm2_fb.c | 65 | ||||
-rw-r--r-- | src/lib/ecore_drm2/ecore_drm2_plane.c | 17 | ||||
-rw-r--r-- | src/lib/ecore_drm2/ecore_drm2_private.h | 9 | ||||
-rw-r--r-- | src/modules/evas/engines/drm/evas_outbuf.c | 2 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_drm/evas_outbuf.c | 2 |
6 files changed, 76 insertions, 52 deletions
diff --git a/src/lib/ecore_drm2/Ecore_Drm2.h b/src/lib/ecore_drm2/Ecore_Drm2.h index af2f396442..7d52d3aa00 100644 --- a/src/lib/ecore_drm2/Ecore_Drm2.h +++ b/src/lib/ecore_drm2/Ecore_Drm2.h @@ -803,16 +803,6 @@ EAPI Ecore_Drm2_Fb *ecore_drm2_fb_create(int fd, int width, int height, int dept EAPI Ecore_Drm2_Fb *ecore_drm2_fb_gbm_create(int fd, int width, int height, int depth, int bpp, unsigned int format, unsigned int handle, unsigned int stride, void *bo); /** - * Destroy a framebuffer object - * - * @param fb - * - * @ingroup Ecore_Drm2_Fb_Group - * @since 1.18 - */ -EAPI void ecore_drm2_fb_destroy(Ecore_Drm2_Fb *fb); - -/** * Get a framebuffer's mmap'd data * * @param fb @@ -901,17 +891,6 @@ EAPI Eina_Bool ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output); EAPI Eina_Bool ecore_drm2_fb_busy_get(Ecore_Drm2_Fb *fb); /** - * Change the Ecore_Drm2_Fb's busy status - * - * @param fb - * @param busy The new busy status - * - * @ingroup Ecore_Drm2_Fb_Group - * @since 1.19 - */ -EAPI void ecore_drm2_fb_busy_set(Ecore_Drm2_Fb *fb, Eina_Bool busy); - -/** * Try to force a framebuffer release for an output * * This tries to release the next or optionally pending, or current @@ -1045,6 +1024,18 @@ EAPI void ecore_drm2_plane_destination_set(Ecore_Drm2_Plane *plane, int x, int y */ EAPI Eina_Bool ecore_drm2_plane_fb_set(Ecore_Drm2_Plane *plane, Ecore_Drm2_Fb *fb); +/** + * Discard a framebuffer object + * + * Decreases the refcount on a fb object. It will be destroyed when it's + * no longer attached to scanout or otherwise in use. + * + * @param fb + * + * @ingroup Ecore_Drm2_Fb_Group + * @since 1.20 + */ +EAPI void ecore_drm2_fb_discard(Ecore_Drm2_Fb *fb); # endif diff --git a/src/lib/ecore_drm2/ecore_drm2_fb.c b/src/lib/ecore_drm2/ecore_drm2_fb.c index 1570895294..b5161c67c2 100644 --- a/src/lib/ecore_drm2/ecore_drm2_fb.c +++ b/src/lib/ecore_drm2/ecore_drm2_fb.c @@ -142,11 +142,13 @@ err: return NULL; } -EAPI void -ecore_drm2_fb_destroy(Ecore_Drm2_Fb *fb) +static void +_ecore_drm2_fb_destroy(Ecore_Drm2_Fb *fb) { EINA_SAFETY_ON_NULL_RETURN(fb); + if (!fb->dead) ERR("Destroying an fb that hasn't been discarded"); + if (fb->mmap) munmap(fb->mmap, fb->sizes[0]); if (fb->id) sym_drmModeRmFB(fb->fd, fb->id); @@ -163,6 +165,32 @@ ecore_drm2_fb_destroy(Ecore_Drm2_Fb *fb) free(fb); } +void +_ecore_drm2_fb_ref(Ecore_Drm2_Fb *fb) +{ + fb->ref++; +} + +void +_ecore_drm2_fb_deref(Ecore_Drm2_Fb *fb) +{ + fb->ref--; + if (fb->ref) return; + + _ecore_drm2_fb_destroy(fb); +} + + +EAPI void +ecore_drm2_fb_discard(Ecore_Drm2_Fb *fb) +{ + EINA_SAFETY_ON_NULL_RETURN(fb); + EINA_SAFETY_ON_TRUE_RETURN(fb->ref < 1); + + fb->dead = EINA_TRUE; + _ecore_drm2_fb_deref(fb); +} + EAPI void * ecore_drm2_fb_data_get(Ecore_Drm2_Fb *fb) { @@ -213,8 +241,8 @@ ecore_drm2_fb_dirty(Ecore_Drm2_Fb *fb, Eina_Rectangle *rects, unsigned int count static void _release_buffer(Ecore_Drm2_Output *output, Ecore_Drm2_Output_State *s) { - s->fb->busy = EINA_FALSE; if (output->release_cb) output->release_cb(output->release_data, s->fb); + _ecore_drm2_fb_deref(s->fb); s->fb = NULL; #ifdef HAVE_ATOMIC_DRM if (s->atomic_req) @@ -226,6 +254,8 @@ _release_buffer(Ecore_Drm2_Output *output, Ecore_Drm2_Output_State *s) EAPI Eina_Bool ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output) { + Ecore_Drm2_Fb *fb; + EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE); if (output->current.fb && (output->current.fb != output->pending.fb)) @@ -249,6 +279,10 @@ ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output) } #endif + EINA_LIST_FREE(output->fbs, fb) + _ecore_drm2_fb_deref(fb); + output->fbs = NULL; + return !!output->next.fb; } @@ -427,7 +461,7 @@ _fb_flip(Ecore_Drm2_Output *output) if (output->current.fb) _release_buffer(output, &output->current); output->current.fb = fb; - output->current.fb->busy = EINA_TRUE; + _ecore_drm2_fb_ref(output->current.fb); output->next.fb = NULL; /* We used to return here, but now that the ticker is fixed this * can leave us hanging waiting for a tick to happen forever. @@ -484,7 +518,7 @@ _fb_flip(Ecore_Drm2_Output *output) else if (ret < 0) { output->next.fb = fb; - output->next.fb->busy = EINA_TRUE; + _ecore_drm2_fb_ref(output->next.fb); return 0; } @@ -501,11 +535,12 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output) if (!output->enabled) return -1; + if (fb) _ecore_drm2_fb_ref(fb); + if (output->pending.fb) { if (output->next.fb) _release_buffer(output, &output->next); output->next.fb = fb; - if (output->next.fb) output->next.fb->busy = EINA_TRUE; return 0; } if (!fb) fb = output->next.fb; @@ -513,14 +548,7 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output) /* So we can generate a tick by flipping to the current fb */ if (!fb) fb = output->current.fb; - if (output->next.fb) - { - output->next.fb->busy = EINA_FALSE; - output->next.fb = NULL; -#ifdef HAVE_ATOMIC_DRM - output->next.atomic_req = NULL; -#endif - } + if (output->next.fb) _release_buffer(output, &output->next); /* If we don't have an fb to set by now, BAIL! */ if (!fb) return -1; @@ -533,7 +561,6 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output) ret = _fb_flip(output); output->pending.fb = output->prep.fb; - output->pending.fb->busy = EINA_TRUE; output->prep.fb = NULL; #ifdef HAVE_ATOMIC_DRM output->pending.atomic_req = output->prep.atomic_req; @@ -546,14 +573,8 @@ EAPI Eina_Bool ecore_drm2_fb_busy_get(Ecore_Drm2_Fb *fb) { EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); - return fb->busy; -} -EAPI void -ecore_drm2_fb_busy_set(Ecore_Drm2_Fb *fb, Eina_Bool busy) -{ - EINA_SAFETY_ON_NULL_RETURN(fb); - fb->busy = busy; + return !!(fb->ref - 1); } EAPI Eina_Bool diff --git a/src/lib/ecore_drm2/ecore_drm2_plane.c b/src/lib/ecore_drm2/ecore_drm2_plane.c index 2bf1917545..a75173bcfc 100644 --- a/src/lib/ecore_drm2/ecore_drm2_plane.c +++ b/src/lib/ecore_drm2/ecore_drm2_plane.c @@ -96,6 +96,7 @@ out: pstate->in_use = EINA_TRUE; pstate->cid.value = output->crtc_id; pstate->fid.value = fb->id; + pstate->fb = fb; pstate->sx.value = 0; pstate->sy.value = 0; @@ -119,8 +120,7 @@ out: return NULL; } - fb->ref++; - + _ecore_drm2_fb_ref(fb); DBG("FB %d assigned to Plane %d", fb->id, pstate->obj_id); output->planes = eina_list_append(output->planes, plane); @@ -133,7 +133,10 @@ ecore_drm2_plane_release(Ecore_Drm2_Plane *plane) EINA_SAFETY_ON_NULL_RETURN(plane); EINA_SAFETY_ON_TRUE_RETURN(plane->dead); + plane->output->fbs = eina_list_append(plane->output->fbs, + plane->state->fb); plane->dead = EINA_TRUE; + plane->state->fb = NULL; plane->state->in_use = EINA_FALSE; _fb_atomic_flip_test(plane->output); } @@ -163,8 +166,14 @@ ecore_drm2_plane_fb_set(Ecore_Drm2_Plane *plane, Ecore_Drm2_Fb *fb) fallback_id = plane->state->fid.value; plane->state->fid.value = fb->id; - if (_fb_atomic_flip_test(plane->output)) return EINA_TRUE; - + if (_fb_atomic_flip_test(plane->output)) + { + _ecore_drm2_fb_ref(fb); + plane->output->fbs = eina_list_append(plane->output->fbs, + plane->state->fb); + plane->state->fb = fb; + return EINA_TRUE; + } plane->state->fid.value = fallback_id; return EINA_FALSE; } diff --git a/src/lib/ecore_drm2/ecore_drm2_private.h b/src/lib/ecore_drm2/ecore_drm2_private.h index b73add3667..2be6069b69 100644 --- a/src/lib/ecore_drm2/ecore_drm2_private.h +++ b/src/lib/ecore_drm2/ecore_drm2_private.h @@ -646,6 +646,7 @@ typedef struct _Ecore_Drm2_Plane_State /* these are not part of an atomic state, but we store these here * so that we do not have to refetch properties when iterating planes */ + Ecore_Drm2_Fb *fb; uint32_t rotation_map[6]; uint32_t supported_rotations; @@ -701,12 +702,11 @@ struct _Ecore_Drm2_Fb uint32_t format; void *gbm_bo; + void *mmap; Eina_Bool gbm : 1; Eina_Bool dmabuf : 1; - Eina_Bool busy : 1; - - void *mmap; + Eina_Bool dead : 1; }; struct _Ecore_Drm2_Plane @@ -795,6 +795,7 @@ struct _Ecore_Drm2_Output Eina_List *plane_states; Eina_List *planes; + Eina_List *fbs; Eina_Bool connected : 1; Eina_Bool primary : 1; @@ -837,6 +838,8 @@ struct _Ecore_Drm2_Device }; Eina_Bool _fb_atomic_flip_test(Ecore_Drm2_Output *output); +void _ecore_drm2_fb_ref(Ecore_Drm2_Fb *); +void _ecore_drm2_fb_deref(Ecore_Drm2_Fb *); /* extern int (*sym_drmClose)(int fd); */ /* extern int (*sym_drmWaitVBlank)(int fd, drmVBlank *vbl); */ diff --git a/src/modules/evas/engines/drm/evas_outbuf.c b/src/modules/evas/engines/drm/evas_outbuf.c index f45e45c119..f890854bb9 100644 --- a/src/modules/evas/engines/drm/evas_outbuf.c +++ b/src/modules/evas/engines/drm/evas_outbuf.c @@ -81,7 +81,7 @@ _outbuf_fb_create(Outbuf *ob, Outbuf_Fb *ofb) static void _outbuf_fb_destroy(Outbuf_Fb *ofb) { - ecore_drm2_fb_destroy(ofb->fb); + ecore_drm2_fb_discard(ofb->fb); memset(ofb, 0, sizeof(*ofb)); ofb->valid = EINA_FALSE; diff --git a/src/modules/evas/engines/gl_drm/evas_outbuf.c b/src/modules/evas/engines/gl_drm/evas_outbuf.c index efc9977195..89eef8c06a 100644 --- a/src/modules/evas/engines/gl_drm/evas_outbuf.c +++ b/src/modules/evas/engines/gl_drm/evas_outbuf.c @@ -41,7 +41,7 @@ _evas_outbuf_fb_cb_destroy(struct gbm_bo *bo EINA_UNUSED, void *data) Ecore_Drm2_Fb *fb; fb = data; - if (fb) ecore_drm2_fb_destroy(fb); + if (fb) ecore_drm2_fb_discard(fb); } static Ecore_Drm2_Fb * |