/** * Limit the number of cores used in some "easy" and impossible cases */ static int limit_blits(int n_split, struct b2r2_blt_req *user_req) { if (n_split <= 1) return n_split; if (user_req->dst_rect.width < 24 && user_req->dst_rect.height < 24) return 1; if (user_req->src_rect.width < n_split && user_req->src_rect.height < n_split) return 1; /* * Handle macroblock formats with one * core for now since there seems to be some bug * related to macroblock access patterns */ if (is_mb_fmt(user_req->src_img.fmt)) return 1; return n_split; }
/** * Split a request rectangle on available cores */ static int b2r2_blt_split_request(struct b2r2_blt_data *blt_data, struct b2r2_blt_req *user_req, struct b2r2_blt_request **split_requests, struct b2r2_control_instance **ctl, int *n_split) { int sstep_x, sstep_y, dstep_x, dstep_y; int dstart_x, dstart_y; int bstart_x, bstart_y; int dpos_x, dpos_y; int bpos_x, bpos_y; int dso_x = 1; int dso_y = 1; int sf_x, sf_y; int i; int srw, srh; int drw, drh; bool ssplit_x = true; bool dsplit_x = true; enum b2r2_blt_transform transform; bool is_rotation = false; bool is_scaling = false; bool bg_blend = false; u32 core_mask = 0; srw = user_req->src_rect.width; srh = user_req->src_rect.height; drw = user_req->dst_rect.width; drh = user_req->dst_rect.height; transform = user_req->transform; /* Early exit in the basic cases */ if (*n_split == 0) { return -ENOSYS; } else if (*n_split == 1 || (srw < *n_split && srh < *n_split) || (drw < *n_split && drh < *n_split) || is_mb_fmt(user_req->src_img.fmt)) { /* * Handle macroblock formats with one * core for now since there seems to be some bug * related to macroblock access patterns */ memcpy(&split_requests[0]->user_req, user_req, sizeof(*user_req)); split_requests[0]->core_mask = (1 << split_requests[0]->instance->control_id); *n_split = 1; return 0; } /* * TODO: fix the load balancing algorithm */ is_rotation = (transform & B2R2_BLT_TRANSFORM_CCW_ROT_90) != 0; /* Check for scaling */ if (is_rotation) { is_scaling = (user_req->src_rect.width != user_req->dst_rect.height) || (user_req->src_rect.height != user_req->dst_rect.width); } else { is_scaling = (user_req->src_rect.width != user_req->dst_rect.width) || (user_req->src_rect.height != user_req->dst_rect.height); } is_scaling = is_scaling || is_scaling_fmt(user_req->src_img.fmt) || is_scaling_fmt(user_req->dst_img.fmt); bg_blend = ((user_req->flags & B2R2_BLT_FLAG_BG_BLEND) != 0); /* * Split the request */ b2r2_log_info(b2r2_blt->dev, "%s: In (t:0x%08X, f:0x%08X):\n" "\tsrc_rect x:%d, y:%d, w:%d, h:%d src fmt:0x%x\n" "\tdst_rect x:%d, y:%d, w:%d, h:%d dst fmt:0x%x\n", __func__, user_req->transform, user_req->flags, user_req->src_rect.x, user_req->src_rect.y, user_req->src_rect.width, user_req->src_rect.height, user_req->src_img.fmt, user_req->dst_rect.x, user_req->dst_rect.y, user_req->dst_rect.width, user_req->dst_rect.height, user_req->dst_img.fmt); /* * TODO: We need sub pixel precision here, * or a better way to split rects */ dstart_x = user_req->dst_rect.x; dstart_y = user_req->dst_rect.y; if (bg_blend) { bstart_x = user_req->bg_rect.x; bstart_y = user_req->bg_rect.y; } if (srw && srh) { if ((srw < srh) && !is_scaling) { ssplit_x = false; sstep_y = srh / *n_split; /* Round up */ if (srh % (*n_split)) sstep_y++; if (srh > 16) sstep_y = ((sstep_y + 16) >> 4) << 4; if (transform & B2R2_BLT_TRANSFORM_CCW_ROT_90) { sf_y = (drw << 10) / srh; dstep_x = (sf_y * sstep_y) >> 10; } else {