summaryrefslogtreecommitdiff
path: root/src/lib/ecore_drm2
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2017-05-12 14:41:03 -0500
committerDerek Foreman <derekf@osg.samsung.com>2017-05-12 17:51:34 -0500
commitedcbff59b72ef8b26af99c1cb3c38f4ffb48282a (patch)
tree3715fc4cdd8906b55969edf4214fdc3f1e7da9d6 /src/lib/ecore_drm2
parent69b941f018a5e289f4eb34adcfdc774c0d9a2409 (diff)
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.
Diffstat (limited to 'src/lib/ecore_drm2')
-rw-r--r--src/lib/ecore_drm2/Ecore_Drm2.h33
-rw-r--r--src/lib/ecore_drm2/ecore_drm2_fb.c65
-rw-r--r--src/lib/ecore_drm2/ecore_drm2_plane.c17
-rw-r--r--src/lib/ecore_drm2/ecore_drm2_private.h9
4 files changed, 74 insertions, 50 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
803EAPI 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); 803EAPI 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);
804 804
805/** 805/**
806 * Destroy a framebuffer object
807 *
808 * @param fb
809 *
810 * @ingroup Ecore_Drm2_Fb_Group
811 * @since 1.18
812 */
813EAPI void ecore_drm2_fb_destroy(Ecore_Drm2_Fb *fb);
814
815/**
816 * Get a framebuffer's mmap'd data 806 * Get a framebuffer's mmap'd data
817 * 807 *
818 * @param fb 808 * @param fb
@@ -901,17 +891,6 @@ EAPI Eina_Bool ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output);
901EAPI Eina_Bool ecore_drm2_fb_busy_get(Ecore_Drm2_Fb *fb); 891EAPI Eina_Bool ecore_drm2_fb_busy_get(Ecore_Drm2_Fb *fb);
902 892
903/** 893/**
904 * Change the Ecore_Drm2_Fb's busy status
905 *
906 * @param fb
907 * @param busy The new busy status
908 *
909 * @ingroup Ecore_Drm2_Fb_Group
910 * @since 1.19
911 */
912EAPI void ecore_drm2_fb_busy_set(Ecore_Drm2_Fb *fb, Eina_Bool busy);
913
914/**
915 * Try to force a framebuffer release for an output 894 * Try to force a framebuffer release for an output
916 * 895 *
917 * This tries to release the next or optionally pending, or current 896 * 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
1045 */ 1024 */
1046EAPI Eina_Bool ecore_drm2_plane_fb_set(Ecore_Drm2_Plane *plane, Ecore_Drm2_Fb *fb); 1025EAPI Eina_Bool ecore_drm2_plane_fb_set(Ecore_Drm2_Plane *plane, Ecore_Drm2_Fb *fb);
1047 1026
1027/**
1028 * Discard a framebuffer object
1029 *
1030 * Decreases the refcount on a fb object. It will be destroyed when it's
1031 * no longer attached to scanout or otherwise in use.
1032 *
1033 * @param fb
1034 *
1035 * @ingroup Ecore_Drm2_Fb_Group
1036 * @since 1.20
1037 */
1038EAPI void ecore_drm2_fb_discard(Ecore_Drm2_Fb *fb);
1048 1039
1049# endif 1040# endif
1050 1041
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:
142 return NULL; 142 return NULL;
143} 143}
144 144
145EAPI void 145static void
146ecore_drm2_fb_destroy(Ecore_Drm2_Fb *fb) 146_ecore_drm2_fb_destroy(Ecore_Drm2_Fb *fb)
147{ 147{
148 EINA_SAFETY_ON_NULL_RETURN(fb); 148 EINA_SAFETY_ON_NULL_RETURN(fb);
149 149
150 if (!fb->dead) ERR("Destroying an fb that hasn't been discarded");
151
150 if (fb->mmap) munmap(fb->mmap, fb->sizes[0]); 152 if (fb->mmap) munmap(fb->mmap, fb->sizes[0]);
151 153
152 if (fb->id) sym_drmModeRmFB(fb->fd, fb->id); 154 if (fb->id) sym_drmModeRmFB(fb->fd, fb->id);
@@ -163,6 +165,32 @@ ecore_drm2_fb_destroy(Ecore_Drm2_Fb *fb)
163 free(fb); 165 free(fb);
164} 166}
165 167
168void
169_ecore_drm2_fb_ref(Ecore_Drm2_Fb *fb)
170{
171 fb->ref++;
172}
173
174void
175_ecore_drm2_fb_deref(Ecore_Drm2_Fb *fb)
176{
177 fb->ref--;
178 if (fb->ref) return;
179
180 _ecore_drm2_fb_destroy(fb);
181}
182
183
184EAPI void
185ecore_drm2_fb_discard(Ecore_Drm2_Fb *fb)
186{
187 EINA_SAFETY_ON_NULL_RETURN(fb);
188 EINA_SAFETY_ON_TRUE_RETURN(fb->ref < 1);
189
190 fb->dead = EINA_TRUE;
191 _ecore_drm2_fb_deref(fb);
192}
193
166EAPI void * 194EAPI void *
167ecore_drm2_fb_data_get(Ecore_Drm2_Fb *fb) 195ecore_drm2_fb_data_get(Ecore_Drm2_Fb *fb)
168{ 196{
@@ -213,8 +241,8 @@ ecore_drm2_fb_dirty(Ecore_Drm2_Fb *fb, Eina_Rectangle *rects, unsigned int count
213static void 241static void
214_release_buffer(Ecore_Drm2_Output *output, Ecore_Drm2_Output_State *s) 242_release_buffer(Ecore_Drm2_Output *output, Ecore_Drm2_Output_State *s)
215{ 243{
216 s->fb->busy = EINA_FALSE;
217 if (output->release_cb) output->release_cb(output->release_data, s->fb); 244 if (output->release_cb) output->release_cb(output->release_data, s->fb);
245 _ecore_drm2_fb_deref(s->fb);
218 s->fb = NULL; 246 s->fb = NULL;
219#ifdef HAVE_ATOMIC_DRM 247#ifdef HAVE_ATOMIC_DRM
220 if (s->atomic_req) 248 if (s->atomic_req)
@@ -226,6 +254,8 @@ _release_buffer(Ecore_Drm2_Output *output, Ecore_Drm2_Output_State *s)
226EAPI Eina_Bool 254EAPI Eina_Bool
227ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output) 255ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output)
228{ 256{
257 Ecore_Drm2_Fb *fb;
258
229 EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE); 259 EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
230 260
231 if (output->current.fb && (output->current.fb != output->pending.fb)) 261 if (output->current.fb && (output->current.fb != output->pending.fb))
@@ -249,6 +279,10 @@ ecore_drm2_fb_flip_complete(Ecore_Drm2_Output *output)
249 } 279 }
250 280
251#endif 281#endif
282 EINA_LIST_FREE(output->fbs, fb)
283 _ecore_drm2_fb_deref(fb);
284 output->fbs = NULL;
285
252 return !!output->next.fb; 286 return !!output->next.fb;
253} 287}
254 288
@@ -427,7 +461,7 @@ _fb_flip(Ecore_Drm2_Output *output)
427 461
428 if (output->current.fb) _release_buffer(output, &output->current); 462 if (output->current.fb) _release_buffer(output, &output->current);
429 output->current.fb = fb; 463 output->current.fb = fb;
430 output->current.fb->busy = EINA_TRUE; 464 _ecore_drm2_fb_ref(output->current.fb);
431 output->next.fb = NULL; 465 output->next.fb = NULL;
432 /* We used to return here, but now that the ticker is fixed this 466 /* We used to return here, but now that the ticker is fixed this
433 * can leave us hanging waiting for a tick to happen forever. 467 * can leave us hanging waiting for a tick to happen forever.
@@ -484,7 +518,7 @@ _fb_flip(Ecore_Drm2_Output *output)
484 else if (ret < 0) 518 else if (ret < 0)
485 { 519 {
486 output->next.fb = fb; 520 output->next.fb = fb;
487 output->next.fb->busy = EINA_TRUE; 521 _ecore_drm2_fb_ref(output->next.fb);
488 return 0; 522 return 0;
489 } 523 }
490 524
@@ -501,11 +535,12 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output)
501 535
502 if (!output->enabled) return -1; 536 if (!output->enabled) return -1;
503 537
538 if (fb) _ecore_drm2_fb_ref(fb);
539
504 if (output->pending.fb) 540 if (output->pending.fb)
505 { 541 {
506 if (output->next.fb) _release_buffer(output, &output->next); 542 if (output->next.fb) _release_buffer(output, &output->next);
507 output->next.fb = fb; 543 output->next.fb = fb;
508 if (output->next.fb) output->next.fb->busy = EINA_TRUE;
509 return 0; 544 return 0;
510 } 545 }
511 if (!fb) fb = output->next.fb; 546 if (!fb) fb = output->next.fb;
@@ -513,14 +548,7 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output)
513 /* So we can generate a tick by flipping to the current fb */ 548 /* So we can generate a tick by flipping to the current fb */
514 if (!fb) fb = output->current.fb; 549 if (!fb) fb = output->current.fb;
515 550
516 if (output->next.fb) 551 if (output->next.fb) _release_buffer(output, &output->next);
517 {
518 output->next.fb->busy = EINA_FALSE;
519 output->next.fb = NULL;
520#ifdef HAVE_ATOMIC_DRM
521 output->next.atomic_req = NULL;
522#endif
523 }
524 552
525 /* If we don't have an fb to set by now, BAIL! */ 553 /* If we don't have an fb to set by now, BAIL! */
526 if (!fb) return -1; 554 if (!fb) return -1;
@@ -533,7 +561,6 @@ ecore_drm2_fb_flip(Ecore_Drm2_Fb *fb, Ecore_Drm2_Output *output)
533 ret = _fb_flip(output); 561 ret = _fb_flip(output);
534 562
535 output->pending.fb = output->prep.fb; 563 output->pending.fb = output->prep.fb;
536 output->pending.fb->busy = EINA_TRUE;
537 output->prep.fb = NULL; 564 output->prep.fb = NULL;
538#ifdef HAVE_ATOMIC_DRM 565#ifdef HAVE_ATOMIC_DRM
539 output->pending.atomic_req = output->prep.atomic_req; 566 output->pending.atomic_req = output->prep.atomic_req;
@@ -546,14 +573,8 @@ EAPI Eina_Bool
546ecore_drm2_fb_busy_get(Ecore_Drm2_Fb *fb) 573ecore_drm2_fb_busy_get(Ecore_Drm2_Fb *fb)
547{ 574{
548 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE); 575 EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
549 return fb->busy;
550}
551 576
552EAPI void 577 return !!(fb->ref - 1);
553ecore_drm2_fb_busy_set(Ecore_Drm2_Fb *fb, Eina_Bool busy)
554{
555 EINA_SAFETY_ON_NULL_RETURN(fb);
556 fb->busy = busy;
557} 578}
558 579
559EAPI Eina_Bool 580EAPI 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:
96 pstate->in_use = EINA_TRUE; 96 pstate->in_use = EINA_TRUE;
97 pstate->cid.value = output->crtc_id; 97 pstate->cid.value = output->crtc_id;
98 pstate->fid.value = fb->id; 98 pstate->fid.value = fb->id;
99 pstate->fb = fb;
99 100
100 pstate->sx.value = 0; 101 pstate->sx.value = 0;
101 pstate->sy.value = 0; 102 pstate->sy.value = 0;
@@ -119,8 +120,7 @@ out:
119 return NULL; 120 return NULL;
120 } 121 }
121 122
122 fb->ref++; 123 _ecore_drm2_fb_ref(fb);
123
124 DBG("FB %d assigned to Plane %d", fb->id, pstate->obj_id); 124 DBG("FB %d assigned to Plane %d", fb->id, pstate->obj_id);
125 output->planes = eina_list_append(output->planes, plane); 125 output->planes = eina_list_append(output->planes, plane);
126 126
@@ -133,7 +133,10 @@ ecore_drm2_plane_release(Ecore_Drm2_Plane *plane)
133 EINA_SAFETY_ON_NULL_RETURN(plane); 133 EINA_SAFETY_ON_NULL_RETURN(plane);
134 EINA_SAFETY_ON_TRUE_RETURN(plane->dead); 134 EINA_SAFETY_ON_TRUE_RETURN(plane->dead);
135 135
136 plane->output->fbs = eina_list_append(plane->output->fbs,
137 plane->state->fb);
136 plane->dead = EINA_TRUE; 138 plane->dead = EINA_TRUE;
139 plane->state->fb = NULL;
137 plane->state->in_use = EINA_FALSE; 140 plane->state->in_use = EINA_FALSE;
138 _fb_atomic_flip_test(plane->output); 141 _fb_atomic_flip_test(plane->output);
139} 142}
@@ -163,8 +166,14 @@ ecore_drm2_plane_fb_set(Ecore_Drm2_Plane *plane, Ecore_Drm2_Fb *fb)
163 166
164 fallback_id = plane->state->fid.value; 167 fallback_id = plane->state->fid.value;
165 plane->state->fid.value = fb->id; 168 plane->state->fid.value = fb->id;
166 if (_fb_atomic_flip_test(plane->output)) return EINA_TRUE; 169 if (_fb_atomic_flip_test(plane->output))
167 170 {
171 _ecore_drm2_fb_ref(fb);
172 plane->output->fbs = eina_list_append(plane->output->fbs,
173 plane->state->fb);
174 plane->state->fb = fb;
175 return EINA_TRUE;
176 }
168 plane->state->fid.value = fallback_id; 177 plane->state->fid.value = fallback_id;
169 return EINA_FALSE; 178 return EINA_FALSE;
170} 179}
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
646 646
647 /* these are not part of an atomic state, but we store these here 647 /* these are not part of an atomic state, but we store these here
648 * so that we do not have to refetch properties when iterating planes */ 648 * so that we do not have to refetch properties when iterating planes */
649 Ecore_Drm2_Fb *fb;
649 uint32_t rotation_map[6]; 650 uint32_t rotation_map[6];
650 uint32_t supported_rotations; 651 uint32_t supported_rotations;
651 652
@@ -701,12 +702,11 @@ struct _Ecore_Drm2_Fb
701 uint32_t format; 702 uint32_t format;
702 703
703 void *gbm_bo; 704 void *gbm_bo;
705 void *mmap;
704 706
705 Eina_Bool gbm : 1; 707 Eina_Bool gbm : 1;
706 Eina_Bool dmabuf : 1; 708 Eina_Bool dmabuf : 1;
707 Eina_Bool busy : 1; 709 Eina_Bool dead : 1;
708
709 void *mmap;
710}; 710};
711 711
712struct _Ecore_Drm2_Plane 712struct _Ecore_Drm2_Plane
@@ -795,6 +795,7 @@ struct _Ecore_Drm2_Output
795 795
796 Eina_List *plane_states; 796 Eina_List *plane_states;
797 Eina_List *planes; 797 Eina_List *planes;
798 Eina_List *fbs;
798 799
799 Eina_Bool connected : 1; 800 Eina_Bool connected : 1;
800 Eina_Bool primary : 1; 801 Eina_Bool primary : 1;
@@ -837,6 +838,8 @@ struct _Ecore_Drm2_Device
837}; 838};
838 839
839Eina_Bool _fb_atomic_flip_test(Ecore_Drm2_Output *output); 840Eina_Bool _fb_atomic_flip_test(Ecore_Drm2_Output *output);
841void _ecore_drm2_fb_ref(Ecore_Drm2_Fb *);
842void _ecore_drm2_fb_deref(Ecore_Drm2_Fb *);
840 843
841/* extern int (*sym_drmClose)(int fd); */ 844/* extern int (*sym_drmClose)(int fd); */
842/* extern int (*sym_drmWaitVBlank)(int fd, drmVBlank *vbl); */ 845/* extern int (*sym_drmWaitVBlank)(int fd, drmVBlank *vbl); */