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.
This commit is contained in:
parent
69b941f018
commit
edcbff59b7
|
@ -802,16 +802,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
|
||||
*
|
||||
|
@ -900,17 +890,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
|
||||
*
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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); */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 *
|
||||
|
|
Loading…
Reference in New Issue