Lines Matching full:crtc

41 #define OPT_CRTC_BLOCKLIST "crtc-blocklist="
228 static int drm_set_plane(drm_ctx *ctx, drm_crtc *crtc, drm_plane *plane, in drm_set_plane() argument
234 if (plane->cursor_plane || crtc->async_commit || !ctx->atomic) in drm_set_plane()
246 PLANE_PROP_CRTC_ID, crtc->crtc_id); in drm_set_plane()
268 DRM_ERROR("CRTC[%d]: failed to do atomic commit (%d)\n", in drm_set_plane()
269 crtc->crtc_id, errno); in drm_set_plane()
272 return drmModeSetPlane(ctx->fd, plane->plane_id, crtc->crtc_id, fb, 0, in drm_set_plane()
597 drm_crtc *crtc = &ctx->crtcs[ctx->num_crtcs]; in drm_get_ctx() local
602 crtc->crtc_id = c->crtc_id; in drm_get_ctx()
603 crtc->crtc_pipe = i; in drm_get_ctx()
604 crtc->prefer_plane_id = prefer_planes[i] ? prefer_planes[i] : prefer_plane; in drm_get_ctx()
606 DRM_DEBUG("found %d CRTC: %d(%d) (%dx%d) prefer plane: %d\n", in drm_get_ctx()
608 crtc->prefer_plane_id); in drm_get_ctx()
624 drm_crtc *crtc = &ctx->crtcs[j]; in drm_get_ctx() local
625 if (crtc->crtc_id != crtc_id) in drm_get_ctx()
628 DRM_DEBUG("CRTC: %d blocked\n", crtc_id); in drm_get_ctx()
629 crtc->blocked = 1; in drm_get_ctx()
688 #define drm_crtc_bind_plane_force(ctx, crtc, plane) \ argument
689 drm_crtc_bind_plane(ctx, crtc, plane, 1)
691 #define drm_crtc_bind_plane_cursor(ctx, crtc, plane) \ argument
692 drm_crtc_bind_plane(ctx, crtc, plane, 0)
694 static int drm_crtc_bind_plane(drm_ctx *ctx, drm_crtc *crtc, uint32_t plane_id, in drm_crtc_bind_plane() argument
701 /* CRTC already assigned */ in drm_crtc_bind_plane()
702 if (crtc->plane) in drm_crtc_bind_plane()
719 /* Not for this CRTC */ in drm_crtc_bind_plane()
720 if (!(plane->plane->possible_crtcs & (1 << crtc->crtc_pipe))) in drm_crtc_bind_plane()
736 DRM_INFO("CRTC[%d]: using cursor plane\n", crtc->crtc_id); in drm_crtc_bind_plane()
739 crtc->use_afbc_modifier = 1; in drm_crtc_bind_plane()
741 crtc->use_afbc_modifier = 1; in drm_crtc_bind_plane()
743 DRM_DEBUG("CRTC[%d]: bind plane: %d%s\n", crtc->crtc_id, plane->plane_id, in drm_crtc_bind_plane()
744 crtc->use_afbc_modifier ? "(AFBC)" : ""); in drm_crtc_bind_plane()
746 crtc->plane = plane; in drm_crtc_bind_plane()
754 static int drm_crtc_valid(drm_crtc *crtc) in drm_crtc_valid() argument
756 return (crtc->width > 0 && crtc->height > 0) ? 0 : -1; in drm_crtc_valid()
759 static int drm_update_crtc(drm_ctx *ctx, drm_crtc *crtc) in drm_update_crtc() argument
764 c = drmModeGetCrtc(ctx->fd, crtc->crtc_id); in drm_update_crtc()
768 was_connected = drm_crtc_valid(crtc) >= 0; in drm_update_crtc()
769 crtc->width = c->width; in drm_update_crtc()
770 crtc->height = c->height; in drm_update_crtc()
771 connected = drm_crtc_valid(crtc) >= 0; in drm_update_crtc()
776 DRM_DEBUG("CRTC[%d]: %s!\n", crtc->crtc_id, \ in drm_update_crtc()
779 return drm_crtc_valid(crtc); in drm_update_crtc()
782 static int drm_crtc_update_offsets(drm_ctx *ctx, drm_crtc *crtc, in drm_crtc_update_offsets() argument
788 if (drm_update_crtc(ctx, crtc) < 0) in drm_crtc_update_offsets()
796 ctx->scale_from * crtc->width * crtc->height / width / height; in drm_crtc_update_offsets()
807 area_w = crtc->width - width; in drm_crtc_update_offsets()
808 area_h = crtc->height - height; in drm_crtc_update_offsets()
834 #define drm_crtc_disable_cursor(ctx, crtc) \ argument
835 drm_crtc_update_cursor(ctx, crtc, NULL)
837 static int drm_crtc_update_cursor(drm_ctx *ctx, drm_crtc *crtc, in drm_crtc_update_cursor() argument
840 drm_plane *plane = crtc->plane; in drm_crtc_update_cursor()
841 uint32_t old_fb = crtc->cursor_curr.fb; in drm_crtc_update_cursor()
848 DRM_DEBUG("CRTC[%d]: disabling cursor\n", crtc->crtc_id); in drm_crtc_update_cursor()
849 drm_set_plane(ctx, crtc, plane, 0, 0, 0, 0, 0); in drm_crtc_update_cursor()
853 memset(&crtc->cursor_curr, 0, sizeof(drm_cursor_state)); in drm_crtc_update_cursor()
858 if (crtc->cursor_curr.fb == cursor_state->fb && in drm_crtc_update_cursor()
859 crtc->cursor_curr.scaled_x == cursor_state->scaled_x && in drm_crtc_update_cursor()
860 crtc->cursor_curr.scaled_y == cursor_state->scaled_y && in drm_crtc_update_cursor()
861 crtc->cursor_curr.off_x == cursor_state->off_x && in drm_crtc_update_cursor()
862 crtc->cursor_curr.off_y == cursor_state->off_y) { in drm_crtc_update_cursor()
863 crtc->cursor_curr = *cursor_state; in drm_crtc_update_cursor()
873 DRM_DEBUG("CRTC[%d]: setting fb: %d (%dx%d) on plane: %d at (%d,%d)\n", in drm_crtc_update_cursor()
874 crtc->crtc_id, fb, w, h, plane->plane_id, x, y); in drm_crtc_update_cursor()
876 ret = drm_set_plane(ctx, crtc, plane, fb, x, y, w, h); in drm_crtc_update_cursor()
878 DRM_ERROR("CRTC[%d]: failed to set plane (%d)\n", crtc->crtc_id, errno); in drm_crtc_update_cursor()
881 DRM_DEBUG("CRTC[%d]: remove FB: %d\n", crtc->crtc_id, old_fb); in drm_crtc_update_cursor()
885 crtc->cursor_curr = *cursor_state; in drm_crtc_update_cursor()
889 static int drm_crtc_create_fb(drm_ctx *ctx, drm_crtc *crtc, in drm_crtc_create_fb() argument
900 DRM_DEBUG("CRTC[%d]: convert FB from %d (%dx%d) to (%dx%d) offset: (%d,%d)\n", in drm_crtc_create_fb()
901 crtc->crtc_id, handle, width, height, in drm_crtc_create_fb()
904 if (!crtc->egl_ctx) { in drm_crtc_create_fb()
908 if (crtc->use_afbc_modifier) { in drm_crtc_create_fb()
917 crtc->egl_ctx = egl_init_ctx(ctx->fd, ctx->num_surfaces, format, modifier); in drm_crtc_create_fb()
918 if (!crtc->egl_ctx) { in drm_crtc_create_fb()
919 DRM_ERROR("CRTC[%d]: failed to init egl ctx\n", crtc->crtc_id); in drm_crtc_create_fb()
925 egl_convert_fb(ctx->fd, crtc->egl_ctx, handle, width, height, in drm_crtc_create_fb()
928 DRM_ERROR("CRTC[%d]: failed to create FB\n", crtc->crtc_id); in drm_crtc_create_fb()
932 DRM_DEBUG("CRTC[%d]: created FB: %d\n", crtc->crtc_id, cursor_state->fb); in drm_crtc_create_fb()
939 drm_crtc *crtc = data; in drm_crtc_thread_fn() local
940 drm_plane *plane = crtc->plane; in drm_crtc_thread_fn()
945 DRM_DEBUG("CRTC[%d]: thread started\n", crtc->crtc_id); in drm_crtc_thread_fn()
951 snprintf(name, sizeof(name), "drm-cursor[%d]", crtc->crtc_id); in drm_crtc_thread_fn()
952 pthread_setname_np(crtc->thread, name); in drm_crtc_thread_fn()
969 crtc->async_commit = in drm_crtc_thread_fn()
971 if (crtc->async_commit) in drm_crtc_thread_fn()
972 DRM_INFO("CRTC[%d]: using async commit\n", crtc->crtc_id); in drm_crtc_thread_fn()
975 crtc->last_update_time = drm_curr_time(); in drm_crtc_thread_fn()
979 pthread_mutex_lock(&crtc->mutex); in drm_crtc_thread_fn()
980 while (crtc->state != PENDING) in drm_crtc_thread_fn()
981 pthread_cond_wait(&crtc->cond, &crtc->mutex); in drm_crtc_thread_fn()
983 cursor_state = crtc->cursor_next; in drm_crtc_thread_fn()
984 crtc->cursor_next.request = 0; in drm_crtc_thread_fn()
985 crtc->state = IDLE; in drm_crtc_thread_fn()
986 cursor_state.request |= crtc->cursor_curr.request; /* For retry */ in drm_crtc_thread_fn()
987 pthread_mutex_unlock(&crtc->mutex); in drm_crtc_thread_fn()
990 if (drm_crtc_update_offsets(ctx, crtc, &cursor_state) < 0) { in drm_crtc_thread_fn()
991 DRM_DEBUG("CRTC[%d]: unavailable!\n", crtc->crtc_id); in drm_crtc_thread_fn()
992 drm_crtc_disable_cursor(ctx, crtc); in drm_crtc_thread_fn()
1000 DRM_DEBUG("CRTC[%d]: set new cursor %d (%dx%d)\n", in drm_crtc_thread_fn()
1001 crtc->crtc_id, cursor_state.handle, in drm_crtc_thread_fn()
1005 drm_crtc_disable_cursor(ctx, crtc); in drm_crtc_thread_fn()
1009 if (drm_crtc_create_fb(ctx, crtc, &cursor_state) < 0) in drm_crtc_thread_fn()
1012 if (drm_crtc_update_cursor(ctx, crtc, &cursor_state) < 0) { in drm_crtc_thread_fn()
1013 DRM_ERROR("CRTC[%d]: failed to set cursor\n", crtc->crtc_id); in drm_crtc_thread_fn()
1020 DRM_DEBUG("CRTC[%d]: move cursor to (%d[%d],%d[%d])\n", in drm_crtc_thread_fn()
1021 crtc->crtc_id, cursor_state.scaled_x, -cursor_state.off_x, in drm_crtc_thread_fn()
1024 if (!crtc->cursor_curr.handle) { in drm_crtc_thread_fn()
1026 crtc->cursor_curr = cursor_state; in drm_crtc_thread_fn()
1028 } else if (crtc->cursor_curr.off_x != cursor_state.off_x || in drm_crtc_thread_fn()
1029 crtc->cursor_curr.off_y != cursor_state.off_y) { in drm_crtc_thread_fn()
1031 if (drm_crtc_create_fb(ctx, crtc, &cursor_state) < 0) in drm_crtc_thread_fn()
1035 cursor_state.fb = crtc->cursor_curr.fb; in drm_crtc_thread_fn()
1038 if (drm_crtc_update_cursor(ctx, crtc, &cursor_state) < 0) { in drm_crtc_thread_fn()
1039 DRM_ERROR("CRTC[%d]: failed to move cursor\n", crtc->crtc_id); in drm_crtc_thread_fn()
1044 if (!crtc->verified && crtc->cursor_curr.fb) { in drm_crtc_thread_fn()
1045 pthread_mutex_lock(&crtc->mutex); in drm_crtc_thread_fn()
1046 DRM_INFO("CRTC[%d]: it works!\n", crtc->crtc_id); in drm_crtc_thread_fn()
1047 crtc->verified = 1; in drm_crtc_thread_fn()
1048 pthread_cond_signal(&crtc->cond); in drm_crtc_thread_fn()
1049 pthread_mutex_unlock(&crtc->mutex); in drm_crtc_thread_fn()
1053 duration = drm_curr_time() - crtc->last_update_time; in drm_crtc_thread_fn()
1056 crtc->last_update_time = drm_curr_time();; in drm_crtc_thread_fn()
1060 pthread_mutex_lock(&crtc->mutex); in drm_crtc_thread_fn()
1061 crtc->cursor_curr.request = REQ_SET_CURSOR; in drm_crtc_thread_fn()
1062 pthread_cond_signal(&crtc->cond); in drm_crtc_thread_fn()
1063 pthread_mutex_unlock(&crtc->mutex); in drm_crtc_thread_fn()
1068 if (crtc->egl_ctx) in drm_crtc_thread_fn()
1069 egl_free_ctx(crtc->egl_ctx); in drm_crtc_thread_fn()
1071 drm_crtc_disable_cursor(ctx, crtc); in drm_crtc_thread_fn()
1073 pthread_mutex_lock(&crtc->mutex); in drm_crtc_thread_fn()
1074 DRM_DEBUG("CRTC[%d]: thread error\n", crtc->crtc_id); in drm_crtc_thread_fn()
1075 crtc->state = FATAL_ERROR; in drm_crtc_thread_fn()
1077 if (crtc->plane) { in drm_crtc_thread_fn()
1078 drm_free_plane(crtc->plane); in drm_crtc_thread_fn()
1079 crtc->plane = NULL; in drm_crtc_thread_fn()
1082 pthread_cond_signal(&crtc->cond); in drm_crtc_thread_fn()
1083 pthread_mutex_unlock(&crtc->mutex); in drm_crtc_thread_fn()
1088 static int drm_crtc_prepare(drm_ctx *ctx, drm_crtc *crtc) in drm_crtc_prepare() argument
1092 /* Update CRTC if unavailable */ in drm_crtc_prepare()
1093 if (drm_crtc_valid(crtc) < 0) in drm_crtc_prepare()
1094 drm_update_crtc(ctx, crtc); in drm_crtc_prepare()
1096 /* CRTC already assigned */ in drm_crtc_prepare()
1097 if (crtc->plane) in drm_crtc_prepare()
1101 if (crtc->prefer_plane_id) in drm_crtc_prepare()
1102 drm_crtc_bind_plane_force(ctx, crtc, crtc->prefer_plane_id); in drm_crtc_prepare()
1105 for (i = 0; !crtc->plane && i < ctx->pres->count_planes; i++) in drm_crtc_prepare()
1106 drm_crtc_bind_plane_cursor(ctx, crtc, ctx->pres->planes[i]); in drm_crtc_prepare()
1110 for (i = ctx->pres->count_planes; !crtc->plane && i; i--) in drm_crtc_prepare()
1111 drm_crtc_bind_plane_force(ctx, crtc, ctx->pres->planes[i - 1]); in drm_crtc_prepare()
1114 if (!crtc->plane) { in drm_crtc_prepare()
1115 DRM_ERROR("CRTC[%d]: failed to find any plane\n", crtc->crtc_id); in drm_crtc_prepare()
1119 crtc->state = IDLE; in drm_crtc_prepare()
1121 pthread_cond_init(&crtc->cond, NULL); in drm_crtc_prepare()
1122 pthread_mutex_init(&crtc->mutex, NULL); in drm_crtc_prepare()
1123 pthread_create(&crtc->thread, NULL, drm_crtc_thread_fn, crtc); in drm_crtc_prepare()
1130 drm_crtc *crtc = NULL; in drm_get_crtc() local
1134 crtc = &ctx->crtcs[i]; in drm_get_crtc()
1135 if (!crtc_id && drm_update_crtc(ctx, crtc) < 0) in drm_get_crtc()
1138 if (crtc->blocked) in drm_get_crtc()
1141 if (!crtc_id || crtc->crtc_id == crtc_id) in drm_get_crtc()
1146 DRM_ERROR("CRTC[%d]: not available\n", crtc_id); in drm_get_crtc()
1150 return crtc; in drm_get_crtc()
1157 drm_crtc *crtc; in drm_set_cursor() local
1168 crtc = drm_get_crtc(ctx, crtc_id); in drm_set_cursor()
1169 if (!crtc) in drm_set_cursor()
1172 if (drm_crtc_prepare(ctx, crtc) < 0) in drm_set_cursor()
1175 DRM_DEBUG("CRTC[%d]: request setting new cursor %d (%dx%d)\n", in drm_set_cursor()
1176 crtc->crtc_id, handle, width, height); in drm_set_cursor()
1178 pthread_mutex_lock(&crtc->mutex); in drm_set_cursor()
1179 if (crtc->state == FATAL_ERROR) { in drm_set_cursor()
1180 pthread_mutex_unlock(&crtc->mutex); in drm_set_cursor()
1181 DRM_ERROR("CRTC[%d]: failed to set cursor\n", crtc->crtc_id); in drm_set_cursor()
1186 cursor_next = &crtc->cursor_next; in drm_set_cursor()
1188 crtc->cursor_curr.request = 0; in drm_set_cursor()
1197 crtc->state = PENDING; in drm_set_cursor()
1198 pthread_cond_signal(&crtc->cond); in drm_set_cursor()
1205 while (!crtc->verified && crtc->state != FATAL_ERROR && \ in drm_set_cursor()
1206 !crtc->cursor_curr.request) in drm_set_cursor()
1207 pthread_cond_wait(&crtc->cond, &crtc->mutex); in drm_set_cursor()
1210 pthread_mutex_unlock(&crtc->mutex); in drm_set_cursor()
1212 if (crtc->state == FATAL_ERROR) { in drm_set_cursor()
1213 DRM_ERROR("CRTC[%d]: failed to set cursor\n", crtc->crtc_id); in drm_set_cursor()
1223 drm_crtc *crtc; in drm_move_cursor() local
1233 crtc = drm_get_crtc(ctx, crtc_id); in drm_move_cursor()
1234 if (!crtc) in drm_move_cursor()
1237 if (crtc->state == FATAL_ERROR || drm_crtc_prepare(ctx, crtc) < 0) in drm_move_cursor()
1240 if (drm_crtc_valid(crtc) < 0) in drm_move_cursor()
1243 DRM_DEBUG("CRTC[%d]: request moving cursor to (%d,%d) in (%dx%d)\n", in drm_move_cursor()
1244 crtc->crtc_id, x, y, crtc->width, crtc->height); in drm_move_cursor()
1246 pthread_mutex_lock(&crtc->mutex); in drm_move_cursor()
1247 if (crtc->state == FATAL_ERROR) { in drm_move_cursor()
1248 pthread_mutex_unlock(&crtc->mutex); in drm_move_cursor()
1253 cursor_next = &crtc->cursor_next; in drm_move_cursor()
1259 crtc->state = PENDING; in drm_move_cursor()
1260 pthread_cond_signal(&crtc->cond); in drm_move_cursor()
1261 pthread_mutex_unlock(&crtc->mutex); in drm_move_cursor()
1275 DRM_DEBUG("fd: %d crtc: %d handle: %d size: %dx%d (%d, %d)\n", in drmModeSetCursor2()
1289 DRM_DEBUG("fd: %d crtc: %d handle: %d size: %dx%d\n", in drmModeSetCursor()
1294 DRM_INFO("CRTC[%d]: scaling without hotspots, use drmModeSetCursor2()!\n", in drmModeSetCursor()
1302 DRM_DEBUG("fd: %d crtc: %d position: %d,%d\n", fd, crtcId, x, y); in drmModeMoveCursor()