xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkisp_demo/demo/display.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (C) 2020 Rockchip Electronics Co., Ltd.
3  * author: Zhihua Wang, hogan.wang@rock-chips.com
4  *
5  * This software is available to you under a choice of one of two
6  * licenses.  You may choose to be licensed under the terms of the GNU
7  * General Public License (GPL), available from the file
8  * COPYING in the main directory of this source tree, or the
9  * OpenIB.org BSD license below:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      - Redistributions of source code must retain the above
16  *        copyright notice, this list of conditions and the following
17  *        disclaimer.
18  *
19  *      - Redistributions in binary form must reproduce the above
20  *        copyright notice, this list of conditions and the following
21  *        disclaimer in the documentation and/or other materials
22  *        provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  */
33 #include <stdio.h>
34 #include <unistd.h>
35 #include <string.h>
36 
37 #include <rga/RgaApi.h>
38 #include "display.h"
39 #include "rkdrm_display.h"
40 //#include "rkfacial.h"
41 #include "rga_control.h"
42 #include <pthread.h>
43 
44 #define BUF_COUNT 3
45 #define USE_NV12
46 
47 struct display {
48     int fmt;
49     int width;
50     int height;
51     int plane_type;
52     struct drm_dev dev;
53     struct drm_buf buf[BUF_COUNT];
54     int buf_cnt;
55     int rga_fmt;
56 };
57 
58 struct display g_disp;
59 
60 struct window {
61     bo_t bo;
62     int fd;
63     int width;
64     int height;
65     int x;
66     int y;
67     int fmt;
68 };
69 
70 struct window win0, win1, win2;
71 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
72 static pthread_t g_th;
73 
drm_display_init(struct display * disp)74 static int drm_display_init(struct display *disp)
75 {
76     int ret;
77     if (drmInit(&disp->dev)) {
78         fprintf(stderr, "drmInit: Failed\n");
79         return -1;
80     }
81 
82     for (int i = 0; i < disp->buf_cnt; i++) {
83         ret = drmGetBuffer(disp->dev.drm_fd, disp->width, disp->height, disp->fmt, &disp->buf[i]);
84         if (ret) {
85             fprintf(stderr, "Alloc drm buffer failed, %d\n", i);
86             return -1;
87         }
88     }
89 
90     return 0;
91 }
92 
display_compose(void * srcp,int srcw,int srch,int fmt,int x,int y)93 static void display_compose(void *srcp, int srcw, int srch, int fmt, int x, int y)
94 {
95     rga_info_t src, dst;
96     memset(&src, 0, sizeof(rga_info_t));
97     src.fd = -1;
98     src.virAddr = srcp;
99     src.mmuFlag = 1;
100     rga_set_rect(&src.rect, 0, 0, srcw, srch, srcw, srch, fmt);
101     memset(&dst, 0, sizeof(rga_info_t));
102     dst.fd = -1;
103     dst.virAddr = win0.bo.ptr;
104     dst.mmuFlag = 1;
105     rga_set_rect(&dst.rect, x, y, srcw, srch, win0.width, win0.height, fmt);
106     if (c_RkRgaBlit(&src, &dst, NULL))
107         printf("%s: rga fail\n", __func__);
108 }
109 
display_win_thread(void * arg)110 static void *display_win_thread(void *arg)
111 {
112     while (1) {
113         pthread_mutex_lock(&lock);
114         display_compose(win1.bo.ptr, win1.width, win1.height, win1.fmt, win1.x, win1.y);
115         display_compose(win2.bo.ptr, win2.width, win2.height, win2.fmt, win2.x, win2.y);
116         pthread_mutex_unlock(&lock);
117         display_commit(win0.bo.ptr, win0.fd, win0.fmt, win0.width, win0.height, 0);
118         usleep(10000);
119     }
120     pthread_exit(NULL);
121 }
122 
display_init(int width,int height)123 int display_init(int width, int height)
124 {
125     int ret;
126 #ifdef USE_NV12
127     g_disp.fmt = DRM_FORMAT_NV12;
128     g_disp.rga_fmt = RK_FORMAT_YCbCr_420_SP;
129 #endif
130 #ifdef USE_RGB888
131     g_disp.fmt = DRM_FORMAT_BGR888;
132     g_disp.rga_fmt = RK_FORMAT_RGB_888;
133 #endif
134     g_disp.width = width;
135     g_disp.height = height;
136     g_disp.plane_type = DRM_PLANE_TYPE_OVERLAY;
137     g_disp.buf_cnt = BUF_COUNT;
138     ret = drm_display_init(&g_disp);
139     if (ret)
140         return ret;
141 
142     win0.width = 720;
143     win0.height = 1280;
144     rga_control_buffer_init(&win0.bo, &win0.fd, win0.width, win0.height, 12);
145     win1.width = 720;
146     win1.height = 640;
147     rga_control_buffer_init(&win1.bo, &win1.fd, win1.width, win1.height, 12);
148     win2.width = 720;
149     win2.height = 640;
150     win2.x = 0;
151     win2.y = 640;
152     rga_control_buffer_init(&win2.bo, &win2.fd, win2.width, win2.height, 12);
153 
154     if (pthread_create(&g_th, NULL, display_win_thread, NULL)) {
155         printf("%s create fail!\n", __func__);
156         return -1;
157     }
158 
159     return 0;
160 }
161 
162 
drm_display_exit(struct display * disp)163 static void drm_display_exit(struct display *disp)
164 {
165     drmDeinit(&disp->dev);
166     for (int i = 0; i < disp->buf_cnt; i++)
167         drmPutBuffer(disp->dev.drm_fd, &disp->buf[i]);
168 
169     rga_control_buffer_deinit(&win0.bo, win0.fd);
170     rga_control_buffer_deinit(&win1.bo, win1.fd);
171     rga_control_buffer_deinit(&win2.bo, win2.fd);
172 }
173 
display_exit(void)174 void display_exit(void)
175 {
176     drm_display_exit(&g_disp);
177 }
178 
drm_commit(struct display * disp,int num,void * ptr,int fd,int fmt,int w,int h,int rotation)179 void drm_commit(struct display *disp, int num, void *ptr, int fd, int fmt, int w, int h, int rotation)
180 {
181     int ret;
182     rga_info_t src, dst;
183     char *map = disp->buf[num].map;
184     int dst_w = disp->width;
185     int dst_h = disp->height;
186     int dst_fmt = disp->rga_fmt;
187 
188     memset(&src, 0, sizeof(rga_info_t));
189     src.fd = -1;
190     src.virAddr = ptr;
191     src.mmuFlag = 1;
192     src.rotation = rotation;
193     rga_set_rect(&src.rect, 0, 0, w, h, w, h, fmt);
194     memset(&dst, 0, sizeof(rga_info_t));
195     dst.fd = -1;
196     dst.virAddr = map;
197     dst.mmuFlag = 1;
198     rga_set_rect(&dst.rect, 0, 0, dst_w, dst_h, dst_w, dst_h, dst_fmt);
199     if (c_RkRgaBlit(&src, &dst, NULL)) {
200         printf("%s: rga fail\n", __func__);
201         return;
202     }
203 
204     ret = drmCommit(&disp->buf[num], disp->width, disp->height, 0, 0, &disp->dev, disp->plane_type);
205     if (ret) {
206         fprintf(stderr, "display commit error, ret = %d\n", ret);
207     }
208 }
209 
display_commit(void * ptr,int fd,int fmt,int w,int h,int rotation)210 void display_commit(void *ptr, int fd, int fmt, int w, int h, int rotation)
211 {
212     static int num = 0;
213 
214     drm_commit(&g_disp, num, ptr, fd, fmt, w, h, rotation);
215     num = (num + 1) % BUF_COUNT;
216 }
217 
display_switch(enum display_video_type type)218 void display_switch(enum display_video_type type)
219 {
220 #if 0
221     set_rgb_display(NULL);
222     set_ir_display(NULL);
223     set_usb_display(NULL);
224     if (type == DISPLAY_VIDEO_RGB)
225         set_rgb_display(display_commit);
226     else if (type == DISPLAY_VIDEO_IR)
227         set_ir_display(display_commit);
228     else if (type == DISPLAY_VIDEO_USB)
229         set_usb_display(display_commit);
230 #endif
231 }
232 
display_win(void * srcp,int fmt,int srcw,int srch,int rotation,void * dstp,int dstw,int dsth)233 void display_win(void *srcp, int fmt, int srcw, int srch, int rotation, void *dstp, int dstw, int dsth)
234 {
235     rga_info_t src, dst;
236     memset(&src, 0, sizeof(rga_info_t));
237     src.fd = -1;
238     src.virAddr = srcp;
239     src.mmuFlag = 1;
240     src.rotation = rotation;
241     rga_set_rect(&src.rect, 0, 0, srcw, srch, srcw, srch, fmt);
242     memset(&dst, 0, sizeof(rga_info_t));
243     dst.fd = -1;
244     dst.virAddr = dstp;
245     dst.mmuFlag = 1;
246     rga_set_rect(&dst.rect, 0, 0, dstw, dsth, dstw, dsth, fmt);
247     if (c_RkRgaBlit(&src, &dst, NULL))
248         printf("%s: rga fail\n", __func__);
249 }
250 
display_win1(void * ptr,int fd,int fmt,int w,int h,int rotation)251 void display_win1(void *ptr, int fd, int fmt, int w, int h, int rotation)
252 {
253     pthread_mutex_lock(&lock);
254     win0.fmt = fmt;
255     win1.fmt = fmt;
256     display_win(ptr, fmt, w, h, rotation, win1.bo.ptr, win1.width, win1.height);
257     pthread_mutex_unlock(&lock);
258 }
259 
display_win2(void * ptr,int fd,int fmt,int w,int h,int rotation)260 void display_win2(void *ptr, int fd, int fmt, int w, int h, int rotation)
261 {
262     pthread_mutex_lock(&lock);
263     win0.fmt = fmt;
264     win2.fmt = fmt;
265     display_win(ptr, fmt, w, h, rotation, win2.bo.ptr, win2.width, win2.height);
266     pthread_mutex_unlock(&lock);
267 }
268 
display_get_resolution(int * width,int * height)269 void display_get_resolution(int *width, int *height)
270 {
271     *width = g_disp.width;
272     *height = g_disp.height;
273 }
274