Add disp_close, disp_x11_close
[glsdk/omapdrmtest.git] / util / util.c
1 /*
2  * Copyright (C) 2011 Texas Instruments
3  * Author: Rob Clark <rob.clark@linaro.org>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 as published by
7  * the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
22 #include "util.h"
24 #include <drm.h>
26 void disp_kms_usage(void);
27 struct display * disp_kms_open(int argc, char **argv);
29 #ifdef HAVE_X11
30 void disp_x11_usage(void);
31 struct display * disp_x11_open(int argc, char **argv);
32 void disp_x11_close(struct display *disp);
33 #endif
35 void
36 disp_usage(void)
37 {
38 #ifdef HAVE_X11
39         disp_x11_usage();
40 #endif
41         disp_kms_usage();
42 }
44 struct display *
45 disp_open(int argc, char **argv)
46 {
47         struct display *disp;
49 #ifdef HAVE_X11
50         disp = disp_x11_open(argc, argv);
51         if (disp)
52                 return disp;
53 #endif
55         disp = disp_kms_open(argc, argv);
57         if (!disp) {
58                 ERROR("unable to create display");
59         }
61         return disp;
62 }
64 void disp_close(struct display *disp)
65 {
66 #ifdef HAVE_X11
67         disp_x11_close(disp);
68 #endif
69 }
71 struct buffer **
72 disp_get_vid_buffers(struct display *disp, uint32_t n,
73                 uint32_t fourcc, uint32_t w, uint32_t h)
74 {
75         struct buffer **buffers;
76         unsigned int i;
78         buffers = disp->get_vid_buffers(disp, n, fourcc, w, h);
79         if (buffers) {
80                 /* if allocation succeeded, store in the unlocked
81                  * video buffer list
82                  */
83                 list_init(&disp->unlocked);
84                 for (i = 0; i < n; i++)
85                         list_add(&buffers[i]->unlocked, &disp->unlocked);
86         }
88         return buffers;
89 }
91 struct buffer *
92 disp_get_vid_buffer(struct display *disp)
93 {
94         struct buffer *buf = NULL;
95         if (!list_is_empty(&disp->unlocked)) {
96                 buf = list_last_entry(&disp->unlocked, struct buffer, unlocked);
97                 list_del(&buf->unlocked);
99                 /* barrier.. if we are using GPU blitting, we need to make sure
100                  * that the GPU is finished:
101                  */
102                 omap_bo_cpu_prep(buf->bo[0], OMAP_GEM_WRITE);
103                 omap_bo_cpu_fini(buf->bo[0], OMAP_GEM_WRITE);
104         }
105         return buf;
108 void
109 disp_put_vid_buffer(struct display *disp, struct buffer *buf)
111         list_add(&buf->unlocked, &disp->unlocked);
114 struct buffer *
115 disp_get_fb(struct display *disp)
117         struct buffer **bufs = disp_get_buffers(disp, 1);
118         if (!bufs)
119                 return NULL;
120         fill(bufs[0], 42);
121         disp_post_buffer(disp, bufs[0]);
122         return bufs[0];
126 int
127 check_args(int argc, char **argv)
129         int i;
130         for (i = 1; i < argc; i++) {
131                 if (argv[i]) {
132                         ERROR("invalid arg: %s", argv[i]);
133                         return -1;
134                 }
135         }
136         return 0;
139 /* stolen from modetest.c */
140 static void
141 fillRGB4(char *virtual, int n, int width, int height, int stride)
143         int i, j;
144         /* paint the buffer with colored tiles */
145         for (j = 0; j < height; j++) {
146                 uint32_t *fb_ptr = (uint32_t*)((char*)virtual + j * stride);
147                 for (i = 0; i < width; i++) {
148                         div_t d = div(n+i+j, width);
149                         fb_ptr[i] =
150                                         0x00130502 * (d.quot >> 6) +
151                                         0x000a1120 * (d.rem >> 6);
152                 }
153         }
157 /* swap these for big endian.. */
158 #define RED   2
159 #define GREEN 1
160 #define BLUE  0
162 static void
163 fill420(unsigned char *y, unsigned char *u, unsigned char *v,
164                 int cs /*chroma pixel stride */,
165                 int n, int width, int height, int stride)
167         int i, j;
169         /* paint the buffer with colored tiles, in blocks of 2x2 */
170         for (j = 0; j < height; j+=2) {
171                 unsigned char *y1p = y + j * stride;
172                 unsigned char *y2p = y1p + stride;
173                 unsigned char *up = u + (j/2) * stride * cs / 2;
174                 unsigned char *vp = v + (j/2) * stride * cs / 2;
176                 for (i = 0; i < width; i+=2) {
177                         div_t d = div(n+i+j, width);
178                         uint32_t rgb = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6);
179                         unsigned char *rgbp = (unsigned char *)&rgb;
180                         unsigned char y = (0.299 * rgbp[RED]) + (0.587 * rgbp[GREEN]) + (0.114 * rgbp[BLUE]);
182                         *(y2p++) = *(y1p++) = y;
183                         *(y2p++) = *(y1p++) = y;
185                         *up = (rgbp[BLUE] - y) * 0.565 + 128;
186                         *vp = (rgbp[RED] - y) * 0.713 + 128;
187                         up += cs;
188                         vp += cs;
189                 }
190         }
193 static void
194 fill422(unsigned char *virtual, int n, int width, int height, int stride)
196         int i, j;
197         /* paint the buffer with colored tiles */
198         for (j = 0; j < height; j++) {
199                 uint8_t *ptr = (uint8_t*)((char*)virtual + j * stride);
200                 for (i = 0; i < width; i++) {
201                         div_t d = div(n+i+j, width);
202                         uint32_t rgb = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6);
203                         unsigned char *rgbp = (unsigned char *)&rgb;
204                         unsigned char y = (0.299 * rgbp[RED]) + (0.587 * rgbp[GREEN]) + (0.114 * rgbp[BLUE]);
206                         *(ptr++) = y;
207                         *(ptr++) = (rgbp[BLUE] - y) * 0.565 + 128;
208                         *(ptr++) = y;
209                         *(ptr++) = (rgbp[RED] - y) * 0.713 + 128;
210                 }
211         }
215 void
216 fill(struct buffer *buf, int n)
218         int i;
220         for (i = 0; i < buf->nbo; i++)
221                 omap_bo_cpu_prep(buf->bo[i], OMAP_GEM_WRITE);
223         switch(buf->fourcc) {
224         case 0: {
225                 assert(buf->nbo == 1);
226                 fillRGB4(omap_bo_map(buf->bo[0]), n,
227                                 buf->width, buf->height, buf->pitches[0]);
228                 break;
229         }
230         case FOURCC('Y','U','Y','V'): {
231                 assert(buf->nbo == 1);
232                 fill422(omap_bo_map(buf->bo[0]), n,
233                                 buf->width, buf->height, buf->pitches[0]);
234                 break;
235         }
236         case FOURCC('N','V','1','2'): {
237                 unsigned char *y, *u, *v;
238                 assert(buf->nbo == 2);
239                 y = omap_bo_map(buf->bo[0]);
240                 u = omap_bo_map(buf->bo[1]);
241                 v = u + 1;
242                 fill420(y, u, v, 2, n, buf->width, buf->height, buf->pitches[0]);
243                 break;
244         }
245         case FOURCC('I','4','2','0'): {
246                 unsigned char *y, *u, *v;
247                 assert(buf->nbo == 3);
248                 y = omap_bo_map(buf->bo[0]);
249                 u = omap_bo_map(buf->bo[1]);
250                 v = omap_bo_map(buf->bo[2]);
251                 fill420(y, u, v, 1, n, buf->width, buf->height, buf->pitches[0]);
252                 break;
253         }
254         default:
255                 ERROR("invalid format: 0x%08x", buf->fourcc);
256                 break;
257         }
259         for (i = 0; i < buf->nbo; i++)
260                 omap_bo_cpu_fini(buf->bo[i], OMAP_GEM_WRITE);