xref: /OK3568_Linux_fs/external/linux-rga/core/RockchipRga.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (C) 2016 Rockchip Electronics Co., Ltd.
3  * Authors:
4  *  Zhiqin Wei <wzq@rock-chips.com>
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #define LOG_NDEBUG 0
20 #ifdef LOG_TAG
21 #undef LOG_TAG
22 #define LOG_TAG "rockchiprga"
23 #endif
24 
25 #include <stdint.h>
26 #include <sys/types.h>
27 #include <sys/ioctl.h>
28 #include <math.h>
29 #include <fcntl.h>
30 #include <signal.h>
31 #include <time.h>
32 
33 #ifdef ANDROID
34 #include <utils/misc.h>
35 #include <cutils/properties.h>
36 #include "core/NormalRga.h"
37 
38 #ifndef ANDROID_8
39 #include <gui/Surface.h>
40 #include <binder/IPCThreadState.h>
41 #include <gui/SurfaceComposerClient.h>
42 #endif
43 
44 #include <android/log.h>
45 #include <log/log_main.h>
46 #include <utils/Atomic.h>
47 #include <utils/Errors.h>
48 #include <utils/Log.h>
49 #include <utils/Mutex.h>
50 #include <utils/Singleton.h>
51 #include <ui/PixelFormat.h>
52 #include <ui/GraphicBufferMapper.h>
53 #endif
54 
55 #include "RockchipRga.h"
56 
57 #ifdef LINUX
58 #include "NormalRga.h"
59 #include "drm.h"
60 #include "drm_mode.h"
61 #endif
62 
63 #include "im2d_api/im2d.h"
64 
65 #ifdef LINUX
local_drmIoctl(int fd,unsigned long request,void * arg)66 static int local_drmIoctl(int fd, unsigned long request, void *arg) {
67     int ret;
68 
69     do {
70         ret = ioctl(fd, request, arg);
71     } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
72     return ret;
73 }
74 
local_drmPrimeHandleToFD(int fd,uint32_t handle,uint32_t flags,int * prime_fd)75 static int local_drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd) {
76     struct drm_prime_handle args;
77     int ret;
78 
79     memset(&args, 0, sizeof(args));
80     args.fd = -1;
81     args.handle = handle;
82     args.flags = flags;
83     ret = local_drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
84     if (ret)
85         return ret;
86 
87     *prime_fd = args.fd;
88     return 0;
89 }
90 #endif
91 
92 #ifdef ANDROID
93 namespace android {
94 // ---------------------------------------------------------------------------
ANDROID_SINGLETON_STATIC_INSTANCE(RockchipRga)95     ANDROID_SINGLETON_STATIC_INSTANCE(RockchipRga)
96 #else
97 RGA_SINGLETON_STATIC_INSTANCE(RockchipRga)
98 #endif
99 
100     RockchipRga::RockchipRga():
101         mSupportRga(false),
102         mLogOnce(0),
103         mLogAlways(0),
104         mContext(NULL) {
105         RkRgaInit();
106 
107 #ifdef ANDROID
108         property_set("vendor.rga_api.version", RGA_API_VERSION);
109 #endif
110         ALOGE("%s", RGA_API_FULL_VERSION);
111     }
112 
~RockchipRga()113     RockchipRga::~RockchipRga() {
114         RgaDeInit(&mContext);
115     }
116 
RkRgaInit()117     int RockchipRga::RkRgaInit() {
118         int ret = 0;
119 
120         if (mSupportRga)
121             return 0;
122 
123         ret = RgaInit(&mContext);
124         if(ret == 0)
125             mSupportRga = true;
126         else
127             mSupportRga = false;
128 
129         return ret;
130     }
131 
RkRgaDeInit()132     void RockchipRga::RkRgaDeInit() {
133         if (mSupportRga)
134             RgaDeInit(&mContext);
135 
136         mSupportRga = false;
137     }
138 
RkRgaGetContext(void ** ctx)139     void RockchipRga::RkRgaGetContext(void **ctx) {
140         *ctx = mContext;
141     }
142 
143 #ifdef LINUX
RkRgaAllocBuffer(int drm_fd,bo_t * bo_info,int width,int height,int bpp,int flags)144     int RockchipRga::RkRgaAllocBuffer(int drm_fd, bo_t *bo_info, int width,
145                                       int height, int bpp, int flags) {
146         struct drm_mode_create_dumb arg;
147         int ret;
148 
149         memset(&arg, 0, sizeof(arg));
150         arg.bpp = bpp;
151         arg.width = width;
152         arg.height = height;
153         arg.flags = flags;
154 
155         ret = local_drmIoctl(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
156         if (ret) {
157             fprintf(stderr, "failed to create dumb buffer: %s\n", strerror(errno));
158             return ret;
159         }
160 
161         bo_info->handle = arg.handle;
162         bo_info->size = arg.size;
163         bo_info->pitch = arg.pitch;
164 
165         return 0;
166     }
167 
RkRgaFreeBuffer(int drm_fd,bo_t * bo_info)168     int RockchipRga::RkRgaFreeBuffer(int drm_fd, bo_t *bo_info) {
169         struct drm_mode_destroy_dumb arg;
170         int ret;
171 
172         if (bo_info->handle <= 0)
173             return -EINVAL;
174         memset(&arg, 0, sizeof(arg));
175         arg.handle = bo_info->handle;
176         ret = local_drmIoctl(drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg);
177         if (ret) {
178             fprintf(stderr, "failed to destroy dumb buffer: %s\n", strerror(errno));
179             return -errno;
180         }
181         bo_info->handle = 0;
182 
183         return 0;
184 
185     }
186 
RkRgaGetAllocBufferExt(bo_t * bo_info,int width,int height,int bpp,int flags)187     int RockchipRga::RkRgaGetAllocBufferExt(bo_t *bo_info, int width, int height, int bpp, int flags) {
188         static const char* card = "/dev/dri/card0";
189         int ret;
190         int drm_fd;
191         int flag = O_RDWR;
192 #ifdef O_CLOEXEC
193         flag |= O_CLOEXEC;
194 #endif
195         bo_info->fd = -1;
196         bo_info->handle = 0;
197         drm_fd = open(card, flag);
198         if (drm_fd < 0) {
199             fprintf(stderr, "Fail to open %s: %m\n", card);
200             return -errno;
201         }
202         ret = RkRgaAllocBuffer(drm_fd, bo_info, width, height, bpp, flags);
203         if (ret) {
204             close(drm_fd);
205             return ret;
206         }
207         bo_info->fd = drm_fd;
208         return 0;
209     }
210 
RkRgaGetAllocBuffer(bo_t * bo_info,int width,int height,int bpp)211     int RockchipRga::RkRgaGetAllocBuffer(bo_t *bo_info, int width, int height, int bpp) {
212         return RkRgaGetAllocBufferExt(bo_info, width, height, bpp, 0);
213     }
214 
RkRgaGetAllocBufferCache(bo_t * bo_info,int width,int height,int bpp)215     int RockchipRga::RkRgaGetAllocBufferCache(bo_t *bo_info, int width, int height, int bpp) {
216         return RkRgaGetAllocBufferExt(bo_info, width, height, bpp, ROCKCHIP_BO_CACHABLE);
217     }
218 
RkRgaGetMmap(bo_t * bo_info)219     int RockchipRga::RkRgaGetMmap(bo_t *bo_info) {
220         struct drm_mode_map_dumb arg;
221         void *map;
222         int ret;
223 
224         memset(&arg, 0, sizeof(arg));
225         arg.handle = bo_info->handle;
226         ret = local_drmIoctl(bo_info->fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
227         if (ret)
228             return ret;
229         map = mmap64(0, bo_info->size, PROT_READ | PROT_WRITE, MAP_SHARED, bo_info->fd, arg.offset);
230         if (map == MAP_FAILED)
231             return -EINVAL;
232         bo_info->ptr = map;
233         return 0;
234     }
235 
RkRgaUnmap(bo_t * bo_info)236     int RockchipRga::RkRgaUnmap(bo_t *bo_info) {
237         munmap(bo_info->ptr, bo_info->size);
238         bo_info->ptr = NULL;
239         return 0;
240     }
241 
RkRgaFree(bo_t * bo_info)242     int RockchipRga::RkRgaFree(bo_t *bo_info) {
243         int ret;
244         if (bo_info->fd < 0)
245             return -EINVAL;
246         ret = RkRgaFreeBuffer(bo_info->fd, bo_info);
247         close(bo_info->fd);
248         bo_info->fd = -1;
249         return ret;
250     }
251 
RkRgaGetBufferFd(bo_t * bo_info,int * fd)252     int RockchipRga::RkRgaGetBufferFd(bo_t *bo_info, int *fd) {
253         int ret = 0;
254         ret = local_drmPrimeHandleToFD(bo_info->fd, bo_info->handle, DRM_CLOEXEC | DRM_RDWR, fd);
255         return ret;
256     }
257 #endif
258 
259 #ifdef ANDROID
RkRgaGetBufferFd(buffer_handle_t handle,int * fd)260     int RockchipRga::RkRgaGetBufferFd(buffer_handle_t handle, int *fd) {
261         int ret = 0;
262         ret = RkRgaGetHandleFd(handle, fd);
263         return ret;
264     }
265 
RkRgaGetHandleMapCpuAddress(buffer_handle_t handle,void ** buf)266     int RockchipRga::RkRgaGetHandleMapCpuAddress(buffer_handle_t handle, void **buf) {
267         int ret = 0;
268         ret = RkRgaGetHandleMapAddress(handle, buf);
269         return ret;
270     }
271 #endif
272 
RkRgaBlit(rga_info * src,rga_info * dst,rga_info * src1)273     int RockchipRga::RkRgaBlit(rga_info *src, rga_info *dst, rga_info *src1) {
274         int ret = 0;
275         ret = RgaBlit(src, dst, src1);
276         if (ret) {
277             RkRgaLogOutUserPara(src);
278             RkRgaLogOutUserPara(dst);
279             RkRgaLogOutUserPara(src1);
280             ALOGE("This output the user parameters when rga call blit fail");
281         }
282         return ret;
283     }
284 
RkRgaFlush()285     int RockchipRga::RkRgaFlush() {
286         int ret = 0;
287         ret = RgaFlush();
288         if (ret) {
289             ALOGE("RgaFlush Failed");
290         }
291         return ret;
292     }
293 
RkRgaCollorFill(rga_info * dst)294     int RockchipRga::RkRgaCollorFill(rga_info *dst) {
295         int ret = 0;
296         ret = RgaCollorFill(dst);
297         return ret;
298     }
299 
RkRgaCollorPalette(rga_info * src,rga_info * dst,rga_info * lut)300     int RockchipRga::RkRgaCollorPalette(rga_info *src, rga_info *dst, rga_info *lut) {
301         int ret = 0;
302         ret = RgaCollorPalette(src, dst, lut);
303         if (ret) {
304             RkRgaLogOutUserPara(src);
305             RkRgaLogOutUserPara(dst);
306             ALOGE("This output the user parameters when rga call CollorPalette fail");
307         }
308         return ret;
309     }
310 
RkRgaLogOutUserPara(rga_info * rgaInfo)311     int RockchipRga::RkRgaLogOutUserPara(rga_info *rgaInfo) {
312         if (!rgaInfo)
313             return -EINVAL;
314 
315         ALOGE("handl-fd-vir-phy-hnd-format[%d, %d, %p, %p, %lx, %d]",
316               rgaInfo->handle, rgaInfo->fd, rgaInfo->virAddr, rgaInfo->phyAddr,
317               (unsigned long)rgaInfo->hnd, rgaInfo->format);
318         ALOGE("rect[%d, %d, %d, %d, %d, %d, %d, %d]",
319               rgaInfo->rect.xoffset, rgaInfo->rect.yoffset,
320               rgaInfo->rect.width,   rgaInfo->rect.height, rgaInfo->rect.wstride,
321               rgaInfo->rect.hstride, rgaInfo->rect.format, rgaInfo->rect.size);
322         ALOGE("f-blend-size-rotation-col-log-mmu[%d, %x, %d, %d, %d, %d, %d]",
323               rgaInfo->format, rgaInfo->blend, rgaInfo->bufferSize,
324               rgaInfo->rotation, rgaInfo->color, rgaInfo->testLog, rgaInfo->mmuFlag);
325         return 0;
326     }
327 
328 // ---------------------------------------------------------------------------
329 #ifdef ANDROID
330 }; // namespace android
331 #endif
332 
333