Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4fedca0 authored by Ramakant Singh's avatar Ramakant Singh Committed by Ian Maund
Browse files

msm: mdss: Blit optimazation for overlaping layers



Optimize blit requests when two consecutive blit requests have same
destination ROI.

Change-Id: Ie87e0190c7a1fd961c21fa79bb08c7bdb8fb6456
Signed-off-by: default avatarRamakant Singh <ramaka@codeaurora.org>
[imaund@codeaurora.org: Resolved context conflicts]
Signed-off-by: default avatarIan Maund <imaund@codeaurora.org>
parent 51f95452
Loading
Loading
Loading
Loading
+113 −20
Original line number Diff line number Diff line
@@ -242,6 +242,12 @@ int mdp3_ppp_verify_scale(struct mdp_blit_req *req)
/* operation check */
int mdp3_ppp_verify_op(struct mdp_blit_req *req)
{
	/*
	 * MDP_DEINTERLACE & MDP_SHARPENING Flags are not valid for MDP3
	 * so using them together for MDP_SMART_BLIT.
	 */
	if ((req->flags & MDP_SMART_BLIT) == MDP_SMART_BLIT)
		return 0;
	if (req->flags & MDP_DEINTERLACE) {
		pr_err("\n%s(): deinterlace not supported", __func__);
		return -EINVAL;
@@ -457,7 +463,8 @@ int mdp3_calc_ppp_res(struct msm_fb_data_type *mfd, struct blit_req_list *lreq)
	u32 dst_write_bw = 0;
	u64 honest_ppp_ab = 0;
	u32 fps = 0;

	int smart_blit_fg_indx = -1;
	u32 smart_blit_bg_read_bw = 0;
	ATRACE_BEGIN(__func__);
	lcount = lreq->count;
	if (lcount == 0) {
@@ -495,6 +502,22 @@ int mdp3_calc_ppp_res(struct msm_fb_data_type *mfd, struct blit_req_list *lreq)
			fps = panel_info->mipi.frame_rate;
		}

		if (lreq->req_list[i].flags & MDP_SMART_BLIT) {
			/*
			 * Flag for smart blit FG layer index
			 * If blit request at index "n" has
			 * MDP_SMART_BLIT flag set then it will be used as BG
			 * layer in smart blit and request at index "n+1"
			 * will be used as FG layer
			 */
			smart_blit_fg_indx = i + 1;
			bg_read_bw = req->src_rect.w * req->src_rect.h *
						bpp.bpp_num / bpp.bpp_den;
			bg_read_bw = mdp3_adjust_scale_factor(req,
						bg_read_bw, bpp.bpp_pln);
			/* Cache read BW of smart blit BG layer */
			smart_blit_bg_read_bw = bg_read_bw;
		} else {
			src_read_bw = req->src_rect.w * req->src_rect.h *
						bpp.bpp_num / bpp.bpp_den;
			src_read_bw = mdp3_adjust_scale_factor(req,
@@ -502,6 +525,10 @@ int mdp3_calc_ppp_res(struct msm_fb_data_type *mfd, struct blit_req_list *lreq)

			mdp3_get_bpp_info(req->dst.format, &bpp);

			if (smart_blit_fg_indx == i) {
				bg_read_bw = smart_blit_bg_read_bw;
				smart_blit_fg_indx = -1;
			} else {
				if ((req->transp_mask != MDP_TRANSP_NOP) ||
					(req->alpha < MDP_ALPHA_NOP) ||
					(req->src.format == MDP_ARGB_8888) ||
@@ -514,10 +541,12 @@ int mdp3_calc_ppp_res(struct msm_fb_data_type *mfd, struct blit_req_list *lreq)
				} else {
					bg_read_bw = 0;
				}
			}
			dst_write_bw = req->dst_rect.w * req->dst_rect.h *
						bpp.bpp_num / bpp.bpp_den;
			honest_ppp_ab += (src_read_bw + bg_read_bw + dst_write_bw);
                }
	}

	if (fps != 0)
		honest_ppp_ab = honest_ppp_ab * fps;
@@ -593,6 +622,10 @@ void mdp3_start_ppp(struct ppp_blit_op *blit_op)
		MDP3_REG_WRITE(MDP3_TFETCH_SOLID_FILL,
					DISABLE_SOLID_FILL);
	}
	/* Skip PPP kickoff for SMART_BLIT BG layer */
	if (blit_op->mdp_op & MDPOP_SMART_BLIT)
		pr_debug("Skip mdp3_ppp_kickoff\n");
	else
		mdp3_ppp_kickoff();
}

@@ -661,6 +694,7 @@ static int mdp3_ppp_process_req(struct ppp_blit_op *blit_op,
	blit_op->src.roi.height = req->src_rect.h;

	blit_op->src.prop.width = req->src.width;
	blit_op->src.prop.height = req->src.height;
	blit_op->src.color_fmt = req->src.format;


@@ -741,6 +775,10 @@ static int mdp3_ppp_process_req(struct ppp_blit_op *blit_op,
	} else {
		blit_op->solid_fill = false;
	}

	if (req->flags & MDP_SMART_BLIT)
		blit_op->mdp_op |= MDPOP_SMART_BLIT;

	return ret;
}

@@ -1189,11 +1227,53 @@ static void mdp3_free_bw_wq_handler(struct work_struct *work)
	mutex_unlock(&ppp_stat->config_ppp_mutex);
}

static bool is_blit_optimization_possible(struct blit_req_list *req, int indx)
{
	int next = indx + 1;
	bool status = false;

	if (next < req->count) {
		/*
		 * Check userspace Smart BLIT Flag for current and next request
		 * Flag for smart blit FG layer index If blit request at index "n" has
		 * MDP_SMART_BLIT flag set then it will be used as BG layer in smart blit
		 * and request at index "n+1" will be used as FG layer
		 */
		if ((req->req_list[indx].flags & MDP_SMART_BLIT) &&
		(!(req->req_list[next].flags & MDP_SMART_BLIT)))
			status = true;
		/*
		 * Enable SMART blit between request 0(BG) & request 1(FG) when
		 * destination ROI of BG and FG layer are same,
		 * No scaling on BG layer
		 * No rotation on BG Layer.
		 * BG Layer color format is RGB
		 */
		else if ((indx == 0) && (!(req->req_list[indx].flags &
			(MDP_ROT_90 | MDP_FLIP_UD | MDP_FLIP_LR))) &&
			(check_if_rgb(req->req_list[indx].src.format)) &&
			(req->req_list[indx].dst_rect.x == req->req_list[next].dst_rect.x) &&
			(req->req_list[indx].dst_rect.y == req->req_list[next].dst_rect.y) &&
			(req->req_list[indx].dst_rect.w == req->req_list[next].dst_rect.w) &&
			(req->req_list[indx].dst_rect.h == req->req_list[next].dst_rect.h) &&
			(req->req_list[indx].dst_rect.w == req->req_list[indx].src_rect.w) &&
			(req->req_list[indx].dst_rect.h == req->req_list[indx].src_rect.h)) {
				status = true;
				req->req_list[indx].flags |= MDP_SMART_BLIT;
			}
		}
	if (status)
		pr_debug("Optimize Blit for Layer: %d Req Count %d\n", indx, req->count) ;
	return status;
}

static void mdp3_ppp_blit_wq_handler(struct work_struct *work)
{
	struct msm_fb_data_type *mfd = ppp_stat->mfd;
	struct blit_req_list *req;
	int i, rc = 0;
	bool smart_blit = false;
	int smart_blit_fg_index = -1;

	mutex_lock(&ppp_stat->config_ppp_mutex);
	req = mdp3_ppp_next_req(&ppp_stat->req_q);
@@ -1229,6 +1309,10 @@ static void mdp3_ppp_blit_wq_handler(struct work_struct *work)
		}
		ATRACE_BEGIN("mpd3_ppp_start");
		for (i = 0; i < req->count; i++) {
			smart_blit = is_blit_optimization_possible(req, i);
			if (smart_blit)
				/* Blit request index of FG layer in smart blit */
				smart_blit_fg_index = i + 1;
			if (!(req->req_list[i].flags & MDP_NO_BLIT)) {
				/* Do the actual blit. */
				if (!rc) {
@@ -1237,8 +1321,17 @@ static void mdp3_ppp_blit_wq_handler(struct work_struct *work)
						&req->src_data[i],
						&req->dst_data[i]);
				}
				/* Unmap blit source buffer */
				if (smart_blit == false)
					mdp3_put_img(&req->src_data[i], MDP3_CLIENT_PPP);
				if (smart_blit_fg_index == i) {
					/* Unmap smart blit background buffer */
					mdp3_put_img(&req->src_data[i - 1], MDP3_CLIENT_PPP);
					smart_blit_fg_index = -1;
				}
				mdp3_put_img(&req->dst_data[i], MDP3_CLIENT_PPP);
				smart_blit = false;

			}
		}
		ATRACE_END("mdp3_ppp_start");
+5 −1
Original line number Diff line number Diff line
/* Copyright (c) 2007, 2013 The Linux Foundation. All rights reserved.
/* Copyright (c) 2007, 2013-2015, The Linux Foundation. All rights reserved.
 * Copyright (C) 2007 Google Incorporated
 *
 * This software is licensed under the terms of the GNU General Public
@@ -23,6 +23,8 @@
#define PPP_BLUR_SCALE_MAX 128
#define PPP_LUT_MAX 256

#define MDPOP_SMART_BLIT        BIT(31) /* blit optimization flag */

/* MDP PPP Operations */
#define MDPOP_NOP               0
#define MDPOP_LR                BIT(0)	/* left to right flip */
@@ -393,6 +395,8 @@ struct ppp_edge_rep {
	int32_t luma_repeat_bottom;
};

bool check_if_rgb(int color);

/* func for ppp register values */
uint32_t ppp_bpp(uint32_t type);
uint32_t ppp_src_config(uint32_t type);
+43 −2
Original line number Diff line number Diff line
@@ -1112,6 +1112,7 @@ int config_ppp_op_mode(struct ppp_blit_op *blit_op)
	uint32_t ppp_operation_reg = 0;
	int sv_slice, sh_slice;
	int dv_slice, dh_slice;
	static struct ppp_img_desc bg_img_param;

	sv_slice = sh_slice = dv_slice = dh_slice = 1;

@@ -1188,19 +1189,59 @@ int config_ppp_op_mode(struct ppp_blit_op *blit_op)
		blit_op->dst.p1 = NULL;
	}

	if ((bg_img_param.p0) && (!(blit_op->mdp_op & MDPOP_SMART_BLIT))) {
		/* Use cached smart blit BG layer info in smart Blit FG request */
		blit_op->bg = bg_img_param;
		if (check_if_rgb(blit_op->bg.color_fmt)) {
			blit_op->bg.p1 = 0;
			blit_op->bg.stride1 = 0;
		}
		memset(&bg_img_param, 0, sizeof(bg_img_param));
	} else {
		blit_op->bg = blit_op->dst;
	}
	/* Jumping from Y-Plane to Chroma Plane */
	/* first pixel addr calculation */
	mdp_adjust_start_addr(blit_op, &blit_op->src, sv_slice, sh_slice, 0);
	/* Adjust BG start address for Non SMART Blit*/
	if (blit_op->bg.p0 == blit_op->dst.p0)
		mdp_adjust_start_addr(blit_op, &blit_op->bg, dv_slice, dh_slice, 1);
	mdp_adjust_start_addr(blit_op, &blit_op->dst, dv_slice, dh_slice, 2);

        /* Cache smart blit BG layer info */
	if (blit_op->mdp_op & MDPOP_SMART_BLIT)
                bg_img_param = blit_op->src;

	config_ppp_scale(blit_op, &ppp_operation_reg);

	config_ppp_blend(blit_op, &ppp_operation_reg);

	config_ppp_src(&blit_op->src, yuv2rgb);
	config_ppp_out(&blit_op->dst, yuv2rgb);

	pr_debug("BLIT FG Param Fmt %d (x %d,y %d,w %d,h %d), ROI(x %d,y %d, w\
		 %d, h %d) Addr_P0 %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n",
		blit_op->src.color_fmt, blit_op->src.prop.x, blit_op->src.prop.y,
		blit_op->src.prop.width, blit_op->src.prop.height,
		blit_op->src.roi.x, blit_op->src.roi.y, blit_op->src.roi.width,
		blit_op->src.roi.height, blit_op->src.p0, blit_op->src.stride0,
                blit_op->src.p1, blit_op->src.stride1);
	if (blit_op->bg.p0 != blit_op->dst.p0)
		pr_debug("BLIT BG Param Fmt %d (x %d,y %d,w %d,h %d), ROI(x %d,y %d, w\
			 %d, h %d) Addr %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n",
			blit_op->bg.color_fmt, blit_op->bg.prop.x, blit_op->bg.prop.y,
			blit_op->bg.prop.width, blit_op->bg.prop.height,
			blit_op->bg.roi.x, blit_op->bg.roi.y, blit_op->bg.roi.width,
			blit_op->bg.roi.height, blit_op->bg.p0, blit_op->bg.stride0,
	                blit_op->bg.p1, blit_op->bg.stride1);
	pr_debug("BLIT FB Param Fmt %d (x %d,y %d,w %d,h %d), ROI(x %d,y %d, w\
		 %d, h %d) Addr %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n",
		blit_op->dst.color_fmt, blit_op->dst.prop.x, blit_op->dst.prop.y,
		blit_op->dst.prop.width, blit_op->dst.prop.height,
		blit_op->dst.roi.x, blit_op->dst.roi.y, blit_op->dst.roi.width,
		blit_op->dst.roi.height, blit_op->dst.p0, blit_op->src.stride0,
                blit_op->dst.p1, blit_op->dst.stride1);

	PPP_WRITEL(ppp_operation_reg, MDP3_PPP_OP_MODE);
	mb();
	return 0;
+6 −0
Original line number Diff line number Diff line
@@ -228,6 +228,12 @@ enum {
#define MDP_TRANSP_NOP 0xffffffff
#define MDP_ALPHA_NOP 0xff

/*
 * MDP_DEINTERLACE & MDP_SHARPENING Flags are not valid for MDP3
 * so using them together for MDP_SMART_BLIT.
 */
#define MDP_SMART_BLIT			0xC0000000

#define MDP_FB_PAGE_PROTECTION_NONCACHED         (0)
#define MDP_FB_PAGE_PROTECTION_WRITECOMBINE      (1)
#define MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE (2)