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