xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkisp_demo/demo/drmDsp.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun #include <stdio.h>
2*4882a593Smuzhiyun #include <linux/fb.h>
3*4882a593Smuzhiyun #include <fcntl.h>
4*4882a593Smuzhiyun #include <unistd.h>
5*4882a593Smuzhiyun #include <stdlib.h>
6*4882a593Smuzhiyun #include <sys/mman.h>
7*4882a593Smuzhiyun #include <drm_fourcc.h>
8*4882a593Smuzhiyun #include <string.h>
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include "./drmDsp/dev.h"
11*4882a593Smuzhiyun #include "./drmDsp/bo.h"
12*4882a593Smuzhiyun #include "./drmDsp/modeset.h"
13*4882a593Smuzhiyun #include "./include/xf86drm.h"
14*4882a593Smuzhiyun #include "./include/xf86drmMode.h"
15*4882a593Smuzhiyun #include "drmDsp.h"
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #if ISPDEMO_ENABLE_RGA
18*4882a593Smuzhiyun #include "rkRgaApi.h"
19*4882a593Smuzhiyun #include "rga.h"
20*4882a593Smuzhiyun #endif
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun struct drmDsp {
23*4882a593Smuzhiyun   struct fb_var_screeninfo vinfo;
24*4882a593Smuzhiyun   unsigned long screensize;
25*4882a593Smuzhiyun   char* fbp;
26*4882a593Smuzhiyun   struct sp_dev* dev;
27*4882a593Smuzhiyun   struct sp_plane** plane;
28*4882a593Smuzhiyun   struct sp_crtc* test_crtc;
29*4882a593Smuzhiyun   struct sp_plane* test_plane;
30*4882a593Smuzhiyun   int num_test_planes;
31*4882a593Smuzhiyun   struct sp_bo* bo[2];
32*4882a593Smuzhiyun   struct sp_bo* nextbo;
33*4882a593Smuzhiyun } gDrmDsp;
34*4882a593Smuzhiyun 
initDrmDsp()35*4882a593Smuzhiyun int initDrmDsp() {
36*4882a593Smuzhiyun   int ret = 0, i = 0;
37*4882a593Smuzhiyun   struct drmDsp* pDrmDsp = &gDrmDsp;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun   memset(pDrmDsp, 0, sizeof(struct drmDsp));
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun   pDrmDsp->dev = create_sp_dev();
42*4882a593Smuzhiyun   if (!pDrmDsp->dev) {
43*4882a593Smuzhiyun     printf("Failed to create sp_dev\n");
44*4882a593Smuzhiyun     return -1;
45*4882a593Smuzhiyun   }
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun   ret = initialize_screens(pDrmDsp->dev);
48*4882a593Smuzhiyun   if (ret) {
49*4882a593Smuzhiyun     printf("Failed to initialize screens\n");
50*4882a593Smuzhiyun     return ret;
51*4882a593Smuzhiyun   }
52*4882a593Smuzhiyun   pDrmDsp->plane = (struct sp_plane**)calloc(pDrmDsp->dev->num_planes, sizeof(struct sp_plane*));
53*4882a593Smuzhiyun   if (!pDrmDsp->plane) {
54*4882a593Smuzhiyun     printf("Failed to allocate plane array\n");
55*4882a593Smuzhiyun     return -1;
56*4882a593Smuzhiyun   }
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun   pDrmDsp->test_crtc = &pDrmDsp->dev->crtcs[3];
59*4882a593Smuzhiyun   pDrmDsp->num_test_planes = pDrmDsp->test_crtc->num_planes;
60*4882a593Smuzhiyun   for (i = 0; i < pDrmDsp->test_crtc->num_planes; i++) {
61*4882a593Smuzhiyun     pDrmDsp->plane[i] = get_sp_plane(pDrmDsp->dev, pDrmDsp->test_crtc);
62*4882a593Smuzhiyun     if (is_supported_format(pDrmDsp->plane[i], DRM_FORMAT_NV12)) {
63*4882a593Smuzhiyun       pDrmDsp->test_plane = pDrmDsp->plane[i];
64*4882a593Smuzhiyun 	  break;
65*4882a593Smuzhiyun 	}
66*4882a593Smuzhiyun   }
67*4882a593Smuzhiyun   if (!pDrmDsp->test_plane)
68*4882a593Smuzhiyun     return -1;
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun #if ISPDEMO_ENABLE_RGA
71*4882a593Smuzhiyun   rkRgaInit();
72*4882a593Smuzhiyun #endif
73*4882a593Smuzhiyun   return ret;
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun 
deInitDrmDsp()76*4882a593Smuzhiyun void deInitDrmDsp() {
77*4882a593Smuzhiyun   struct drmDsp* pDrmDsp = &gDrmDsp;
78*4882a593Smuzhiyun   if (pDrmDsp->bo[0])
79*4882a593Smuzhiyun     free_sp_bo(pDrmDsp->bo[0]);
80*4882a593Smuzhiyun   if (pDrmDsp->bo[1])
81*4882a593Smuzhiyun     free_sp_bo(pDrmDsp->bo[1]);
82*4882a593Smuzhiyun   destroy_sp_dev(pDrmDsp->dev);
83*4882a593Smuzhiyun   memset(pDrmDsp, 0, sizeof(struct drmDsp));
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
arm_camera_yuv420_scale_arm(char * srcbuf,char * dstbuf,int src_w,int src_h,int dst_w,int dst_h)86*4882a593Smuzhiyun static int arm_camera_yuv420_scale_arm(char *srcbuf, char *dstbuf,int src_w, int src_h,int dst_w, int dst_h) {
87*4882a593Smuzhiyun 	unsigned char *psY = NULL,*pdY = NULL,*psUV = NULL,*pdUV = NULL;
88*4882a593Smuzhiyun 	// unsigned char *src,*dst;
89*4882a593Smuzhiyun 	int srcW,srcH,cropW,cropH,dstW,dstH;
90*4882a593Smuzhiyun 	long zoomindstxIntInv,zoomindstyIntInv;
91*4882a593Smuzhiyun 	long x,y;
92*4882a593Smuzhiyun 	long yCoeff00,yCoeff01,xCoeff00,xCoeff01;
93*4882a593Smuzhiyun 	long sX,sY;
94*4882a593Smuzhiyun 	long r0,r1,a,b,c,d;
95*4882a593Smuzhiyun 	int nv21DstFmt = 0, mirror = 0;
96*4882a593Smuzhiyun 	int ratio = 0;
97*4882a593Smuzhiyun 	int top_offset=0,left_offset=0;
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	//need crop ?
100*4882a593Smuzhiyun 	if((src_w*100/src_h) != (dst_w*100/dst_h)){
101*4882a593Smuzhiyun 		ratio = ((src_w*100/dst_w) >= (src_h*100/dst_h))?(src_h*100/dst_h):(src_w*100/dst_w);
102*4882a593Smuzhiyun 		cropW = ratio*dst_w/100;
103*4882a593Smuzhiyun 		cropH = ratio*dst_h/100;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 		left_offset=((src_w-cropW)>>1) & (~0x01);
106*4882a593Smuzhiyun 		top_offset=((src_h-cropH)>>1) & (~0x01);
107*4882a593Smuzhiyun 	}else{
108*4882a593Smuzhiyun 		cropW = src_w;
109*4882a593Smuzhiyun 		cropH = src_h;
110*4882a593Smuzhiyun 		top_offset=0;
111*4882a593Smuzhiyun 		left_offset=0;
112*4882a593Smuzhiyun 	}
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	// src = psY = (unsigned char*)(srcbuf)+top_offset*src_w+left_offset;
115*4882a593Smuzhiyun 	//psUV = psY +src_w*src_h+top_offset*src_w/2+left_offset;
116*4882a593Smuzhiyun 	psUV = (unsigned char*)(srcbuf) +src_w*src_h+top_offset*src_w/2+left_offset;
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	srcW =src_w;
120*4882a593Smuzhiyun 	srcH = src_h;
121*4882a593Smuzhiyun //	cropW = src_w;
122*4882a593Smuzhiyun //	cropH = src_h;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	// dst = pdY = (unsigned char*)dstbuf;
126*4882a593Smuzhiyun 	pdUV = pdY + dst_w*dst_h;
127*4882a593Smuzhiyun 	dstW = dst_w;
128*4882a593Smuzhiyun 	dstH = dst_h;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	zoomindstxIntInv = ((unsigned long)(cropW)<<16)/dstW + 1;
131*4882a593Smuzhiyun 	zoomindstyIntInv = ((unsigned long)(cropH)<<16)/dstH + 1;
132*4882a593Smuzhiyun 	//y
133*4882a593Smuzhiyun 	//for(y = 0; y<dstH - 1 ; y++ ) {
134*4882a593Smuzhiyun 	for(y = 0; y<dstH; y++ ) {
135*4882a593Smuzhiyun 		yCoeff00 = (y*zoomindstyIntInv)&0xffff;
136*4882a593Smuzhiyun 		yCoeff01 = 0xffff - yCoeff00;
137*4882a593Smuzhiyun 		sY = (y*zoomindstyIntInv >> 16);
138*4882a593Smuzhiyun 		sY = (sY >= srcH - 1)? (srcH - 2) : sY;
139*4882a593Smuzhiyun 		for(x = 0; x<dstW; x++ ) {
140*4882a593Smuzhiyun 			xCoeff00 = (x*zoomindstxIntInv)&0xffff;
141*4882a593Smuzhiyun 			xCoeff01 = 0xffff - xCoeff00;
142*4882a593Smuzhiyun 			sX = (x*zoomindstxIntInv >> 16);
143*4882a593Smuzhiyun 			sX = (sX >= srcW -1)?(srcW- 2) : sX;
144*4882a593Smuzhiyun 			a = psY[sY*srcW + sX];
145*4882a593Smuzhiyun 			b = psY[sY*srcW + sX + 1];
146*4882a593Smuzhiyun 			c = psY[(sY+1)*srcW + sX];
147*4882a593Smuzhiyun 			d = psY[(sY+1)*srcW + sX + 1];
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 			r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
150*4882a593Smuzhiyun 			r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
151*4882a593Smuzhiyun 			r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 			if(mirror)
154*4882a593Smuzhiyun 				pdY[dstW -1 - x] = r0;
155*4882a593Smuzhiyun 			else
156*4882a593Smuzhiyun 				pdY[x] = r0;
157*4882a593Smuzhiyun 		}
158*4882a593Smuzhiyun 		pdY += dstW;
159*4882a593Smuzhiyun 	}
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	dstW /= 2;
162*4882a593Smuzhiyun 	dstH /= 2;
163*4882a593Smuzhiyun 	srcW /= 2;
164*4882a593Smuzhiyun 	srcH /= 2;
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	//UV
167*4882a593Smuzhiyun 	//for(y = 0; y<dstH - 1 ; y++ ) {
168*4882a593Smuzhiyun 	for(y = 0; y<dstH; y++ ) {
169*4882a593Smuzhiyun 		yCoeff00 = (y*zoomindstyIntInv)&0xffff;
170*4882a593Smuzhiyun 		yCoeff01 = 0xffff - yCoeff00;
171*4882a593Smuzhiyun 		sY = (y*zoomindstyIntInv >> 16);
172*4882a593Smuzhiyun 		sY = (sY >= srcH -1)? (srcH - 2) : sY;
173*4882a593Smuzhiyun 		for(x = 0; x<dstW; x++ ) {
174*4882a593Smuzhiyun 			xCoeff00 = (x*zoomindstxIntInv)&0xffff;
175*4882a593Smuzhiyun 			xCoeff01 = 0xffff - xCoeff00;
176*4882a593Smuzhiyun 			sX = (x*zoomindstxIntInv >> 16);
177*4882a593Smuzhiyun 			sX = (sX >= srcW -1)?(srcW- 2) : sX;
178*4882a593Smuzhiyun 			//U
179*4882a593Smuzhiyun 			a = psUV[(sY*srcW + sX)*2];
180*4882a593Smuzhiyun 			b = psUV[(sY*srcW + sX + 1)*2];
181*4882a593Smuzhiyun 			c = psUV[((sY+1)*srcW + sX)*2];
182*4882a593Smuzhiyun 			d = psUV[((sY+1)*srcW + sX + 1)*2];
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 			r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
185*4882a593Smuzhiyun 			r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
186*4882a593Smuzhiyun 			r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 			if(mirror && nv21DstFmt)
189*4882a593Smuzhiyun 				pdUV[dstW*2-1- (x*2)] = r0;
190*4882a593Smuzhiyun 			else if(mirror)
191*4882a593Smuzhiyun 				pdUV[dstW*2-1-(x*2+1)] = r0;
192*4882a593Smuzhiyun 			else if(nv21DstFmt)
193*4882a593Smuzhiyun 				pdUV[x*2 + 1] = r0;
194*4882a593Smuzhiyun 			else
195*4882a593Smuzhiyun 				pdUV[x*2] = r0;
196*4882a593Smuzhiyun 			//V
197*4882a593Smuzhiyun 			a = psUV[(sY*srcW + sX)*2 + 1];
198*4882a593Smuzhiyun 			b = psUV[(sY*srcW + sX + 1)*2 + 1];
199*4882a593Smuzhiyun 			c = psUV[((sY+1)*srcW + sX)*2 + 1];
200*4882a593Smuzhiyun 			d = psUV[((sY+1)*srcW + sX + 1)*2 + 1];
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 			r0 = (a * xCoeff01 + b * xCoeff00)>>16 ;
203*4882a593Smuzhiyun 			r1 = (c * xCoeff01 + d * xCoeff00)>>16 ;
204*4882a593Smuzhiyun 			r0 = (r0 * yCoeff01 + r1 * yCoeff00)>>16;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 			if(mirror && nv21DstFmt)
207*4882a593Smuzhiyun 				pdUV[dstW*2-1- (x*2+1) ] = r0;
208*4882a593Smuzhiyun 			else if(mirror)
209*4882a593Smuzhiyun 				pdUV[dstW*2-1-(x*2)] = r0;
210*4882a593Smuzhiyun 			else if(nv21DstFmt)
211*4882a593Smuzhiyun 				pdUV[x*2] = r0;
212*4882a593Smuzhiyun 			else
213*4882a593Smuzhiyun 				pdUV[x*2 + 1] = r0;
214*4882a593Smuzhiyun 		}
215*4882a593Smuzhiyun 		pdUV += dstW*2;
216*4882a593Smuzhiyun 	}
217*4882a593Smuzhiyun 	return 0;
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun 
drmDspFrame(int srcWidth,int srcHeight,int dispWidth,int dispHeight,int dmaFd,void * srcAddr,int fmt)220*4882a593Smuzhiyun int drmDspFrame(int srcWidth, int srcHeight, int dispWidth, int dispHeight,
221*4882a593Smuzhiyun 		int dmaFd, void* srcAddr, int fmt)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun   int ret;
224*4882a593Smuzhiyun   // struct drm_mode_create_dumb cd;
225*4882a593Smuzhiyun   struct sp_bo* bo;
226*4882a593Smuzhiyun   struct drmDsp* pDrmDsp = &gDrmDsp;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun   int wAlign16 = ((dispWidth+ 15) & (~15));
229*4882a593Smuzhiyun   int hAlign16 = (dispHeight + 15) & (~15);
230*4882a593Smuzhiyun   // int frameSize = wAlign16 * hAlign16 * 3 / 2;
231*4882a593Smuzhiyun   uint32_t handles[4], pitches[4], offsets[4];
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun   if (DRM_FORMAT_NV12 != fmt) {
234*4882a593Smuzhiyun     printf("%s just support NV12 to display\n", __func__);
235*4882a593Smuzhiyun     return -1;
236*4882a593Smuzhiyun   }
237*4882a593Smuzhiyun   //create bo
238*4882a593Smuzhiyun #if 1
239*4882a593Smuzhiyun   if (!pDrmDsp->bo[0]) {
240*4882a593Smuzhiyun     printf("%s:bo widthxheight:%dx%d\n", __func__, wAlign16, hAlign16);
241*4882a593Smuzhiyun     pDrmDsp->bo[0] = create_sp_bo(pDrmDsp->dev, wAlign16, hAlign16,
242*4882a593Smuzhiyun                                   16, 32, DRM_FORMAT_NV12, 0);
243*4882a593Smuzhiyun     pDrmDsp->bo[1] = create_sp_bo(pDrmDsp->dev, wAlign16, hAlign16,
244*4882a593Smuzhiyun                                   16, 32, DRM_FORMAT_NV12, 0);
245*4882a593Smuzhiyun     if (!pDrmDsp->bo[0] || !pDrmDsp->bo[1]) {
246*4882a593Smuzhiyun       printf("%s:create bo failed ! \n", __func__);
247*4882a593Smuzhiyun       return -1;
248*4882a593Smuzhiyun     }
249*4882a593Smuzhiyun     pDrmDsp->nextbo = pDrmDsp->bo[0];
250*4882a593Smuzhiyun   }
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun   if (!pDrmDsp->nextbo) {
253*4882a593Smuzhiyun     printf("%s:no available bo ! \n", __func__);
254*4882a593Smuzhiyun     return -1;
255*4882a593Smuzhiyun   }
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun   bo = pDrmDsp->nextbo;
258*4882a593Smuzhiyun #else
259*4882a593Smuzhiyun   bo = create_sp_bo(pDrmDsp->dev, wAlign16, hAlign16,
260*4882a593Smuzhiyun                     16, 32, DRM_FORMAT_NV12, 0);
261*4882a593Smuzhiyun   if (!bo)
262*4882a593Smuzhiyun     printf("%s:create bo failed ! \n", __func__);
263*4882a593Smuzhiyun #endif
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun   handles[0] = bo->handle;
266*4882a593Smuzhiyun   pitches[0] = wAlign16;
267*4882a593Smuzhiyun   offsets[0] = 0;
268*4882a593Smuzhiyun   handles[1] = bo->handle;
269*4882a593Smuzhiyun   pitches[1] = wAlign16;
270*4882a593Smuzhiyun   offsets[1] = dispWidth * dispHeight; //wAlign16 * hAlign16;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun #if ISPDEMO_ENABLE_RGA
273*4882a593Smuzhiyun   struct rkRgaCfg src_cfg, dst_cfg;
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun   src_cfg.fd = dmaFd;
276*4882a593Smuzhiyun   src_cfg.addr = 0;
277*4882a593Smuzhiyun   src_cfg.fmt = RK_FORMAT_YCrCb_420_SP;
278*4882a593Smuzhiyun   src_cfg.width = srcWidth;
279*4882a593Smuzhiyun   src_cfg.height = srcHeight;
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun   dst_cfg.fd = bo->fd;
282*4882a593Smuzhiyun   dst_cfg.addr = 0;
283*4882a593Smuzhiyun   dst_cfg.fmt = RK_FORMAT_YCrCb_420_SP;
284*4882a593Smuzhiyun   dst_cfg.width = dispWidth;
285*4882a593Smuzhiyun   dst_cfg.height = dispHeight;
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun   rkRgaBlit(&src_cfg, &dst_cfg);
288*4882a593Smuzhiyun #else
289*4882a593Smuzhiyun   //copy src data to bo
290*4882a593Smuzhiyun   if (srcWidth == dispWidth)
291*4882a593Smuzhiyun 	  memcpy(bo->map_addr, srcAddr, wAlign16 * hAlign16 * 3 / 2);
292*4882a593Smuzhiyun   else
293*4882a593Smuzhiyun 	  arm_camera_yuv420_scale_arm(srcAddr, bo->map_addr, srcWidth, srcHeight, dispWidth, dispHeight);
294*4882a593Smuzhiyun #endif
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun   ret = drmModeAddFB2(bo->dev->fd, bo->width, bo->height,
297*4882a593Smuzhiyun                       bo->format, handles, pitches, offsets,
298*4882a593Smuzhiyun                       &bo->fb_id, bo->flags);
299*4882a593Smuzhiyun   if (ret) {
300*4882a593Smuzhiyun     printf("%s:failed to create fb ret=%d\n", __func__, ret);
301*4882a593Smuzhiyun     printf("fd:%d ,wxh:%ux%u,format:%u,handles:%u,%u,pictches:%u,%u,offsets:%u,%u,fb_id:%u,flags:%u \n",
302*4882a593Smuzhiyun            bo->dev->fd, bo->width, bo->height, bo->format,
303*4882a593Smuzhiyun            handles[0], handles[1], pitches[0], pitches[1],
304*4882a593Smuzhiyun            offsets[0], offsets[1], bo->fb_id, bo->flags);
305*4882a593Smuzhiyun     return ret;
306*4882a593Smuzhiyun   }
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun   ret = drmModeSetPlane(pDrmDsp->dev->fd, pDrmDsp->test_plane->plane->plane_id,
309*4882a593Smuzhiyun                         pDrmDsp->test_crtc->crtc->crtc_id, bo->fb_id, 0, 0, 0,
310*4882a593Smuzhiyun                         //pDrmDsp->test_crtc->crtc->mode.hdisplay,
311*4882a593Smuzhiyun 			wAlign16, hAlign16,
312*4882a593Smuzhiyun                         //pDrmDsp->test_crtc->crtc->mode.vdisplay,
313*4882a593Smuzhiyun                         0, 0, dispWidth << 16,  dispHeight << 16);
314*4882a593Smuzhiyun   if (ret) {
315*4882a593Smuzhiyun     printf("failed to set plane to crtc ret=%d\n", ret);
316*4882a593Smuzhiyun     return ret;
317*4882a593Smuzhiyun   }
318*4882a593Smuzhiyun   //free_sp_bo(bo);
319*4882a593Smuzhiyun #if 0
320*4882a593Smuzhiyun   if (pDrmDsp->test_plane->bo) {
321*4882a593Smuzhiyun     if (pDrmDsp->test_plane->bo->fb_id) {
322*4882a593Smuzhiyun       ret = drmModeRmFB(pDrmDsp->dev->fd, pDrmDsp->test_plane->bo->fb_id);
323*4882a593Smuzhiyun       if (ret)
324*4882a593Smuzhiyun         printf("Failed to rmfb ret=%d!\n", ret);
325*4882a593Smuzhiyun     }
326*4882a593Smuzhiyun     if (pDrmDsp->test_plane->bo->handle) {
327*4882a593Smuzhiyun       struct drm_gem_close req = {
328*4882a593Smuzhiyun         .handle = pDrmDsp->test_plane->bo->handle,
329*4882a593Smuzhiyun       };
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun       drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
332*4882a593Smuzhiyun       printf("%s:close bo success!\n", __func__);
333*4882a593Smuzhiyun     }
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun     if (!pDrmDsp->nextbo)
336*4882a593Smuzhiyun       free_sp_bo(pDrmDsp->test_plane->bo);
337*4882a593Smuzhiyun   }
338*4882a593Smuzhiyun   pDrmDsp->test_plane->bo = bo; //last po
339*4882a593Smuzhiyun #endif
340*4882a593Smuzhiyun #if 1
341*4882a593Smuzhiyun   //switch bo
342*4882a593Smuzhiyun   if (pDrmDsp->nextbo == pDrmDsp->bo[0])
343*4882a593Smuzhiyun     pDrmDsp->nextbo = pDrmDsp->bo[1];
344*4882a593Smuzhiyun   else
345*4882a593Smuzhiyun     pDrmDsp->nextbo = pDrmDsp->bo[0];
346*4882a593Smuzhiyun #endif
347*4882a593Smuzhiyun   return ret;
348*4882a593Smuzhiyun }
349