xref: /OK3568_Linux_fs/external/linux-rga/im2d_api/src/im2d_impl.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (C) 2021 Rockchip Electronics Co., Ltd.
3  * Authors:
4  *  Cerf Yu <cerf.yu@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 #ifdef LOG_TAG
20 #undef LOG_TAG
21 #define LOG_TAG "im2d_rga_impl"
22 #else
23 #define LOG_TAG "im2d_rga_impl"
24 #endif
25 
26 #include <stdio.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <math.h>
30 #include <sys/ioctl.h>
31 
32 #include "im2d.h"
33 #include "im2d_impl.h"
34 #include "im2d_log.h"
35 #include "im2d_hardware.h"
36 
37 #include "RockchipRga.h"
38 #include "core/NormalRga.h"
39 #include "RgaUtils.h"
40 #include "utils.h"
41 
42 #ifdef ANDROID
43 using namespace android;
44 #endif
45 
46 #define MAX(n1, n2) ((n1) > (n2) ? (n1) : (n2))
47 #define GET_GCD(n1, n2) \
48     ({ \
49         int i; \
50         for(i = 1; i <= (n1) && i <= (n2); i++) { \
51             if((n1) % i==0 && (n2) % i==0) \
52                 gcd = i; \
53         } \
54         gcd; \
55     })
56 #define GET_LCM(n1, n2, gcd) (((n1) * (n2)) / gcd)
57 
58 extern struct rgaContext *rgaCtx;
59 
60 struct im2d_job_manager g_im2d_job_manager;
61 __thread im_context_t g_im2d_context;
62 
rga_get_context(void)63 IM_API static IM_STATUS rga_get_context(void) {
64     if (rgaCtx == NULL) {
65         RockchipRga& rkRga(RockchipRga::get());
66         if (rgaCtx == NULL) {
67             IM_LOGE("The current RockchipRga singleton is destroyed. "
68                     "Please check if RkRgaInit/RkRgaDeInit are called, if so, please disable them.");
69             return IM_STATUS_FAILED;
70         }
71     }
72 
73     return IM_STATUS_SUCCESS;
74 }
75 
rga_support_info_merge_table(rga_info_table_entry * dst_table,rga_info_table_entry * merge_table)76 static IM_STATUS rga_support_info_merge_table(rga_info_table_entry *dst_table, rga_info_table_entry *merge_table) {
77     if (dst_table == NULL || merge_table == NULL) {
78         IM_LOGE("%s[%d] dst or merge table is NULL!\n", __FUNCTION__, __LINE__);
79         return IM_STATUS_FAILED;
80     }
81 
82     dst_table->version              |= merge_table->version;
83     dst_table->input_format         |= merge_table->input_format;
84     dst_table->output_format        |= merge_table->output_format;
85     dst_table->feature              |= merge_table->feature;
86 
87     dst_table->input_resolution     = MAX(dst_table->input_resolution, merge_table->input_resolution);
88     dst_table->output_resolution    = MAX(dst_table->output_resolution, merge_table->output_resolution);
89     dst_table->byte_stride          = MAX(dst_table->byte_stride, merge_table->byte_stride);
90     dst_table->scale_limit          = MAX(dst_table->scale_limit, merge_table->scale_limit);
91     dst_table->performance          = MAX(dst_table->performance, merge_table->performance);
92 
93     return IM_STATUS_SUCCESS;
94 }
95 
96 /**
97  * rga_version_compare() - Used to compare two struct rga_version_t.
98  * @param version1
99  * @param version2
100  *
101  * @returns
102  *   if version1 > version2, return >0;
103  *   if version1 = version2, return 0;
104  *   if version1 < version2, retunr <0.
105  */
rga_version_compare(struct rga_version_t version1,struct rga_version_t version2)106 int rga_version_compare(struct rga_version_t version1, struct rga_version_t version2) {
107     if (version1.major > version2.major)
108         return 1;
109     else if (version1.major == version2.major && version1.minor > version2.minor)
110         return 1;
111     else if (version1.major == version2.major && version1.minor == version2.minor && version1.revision > version2.revision)
112         return 1;
113     else if (version1.major == version2.major && version1.minor == version2.minor && version1.revision == version2.revision)
114         return 0;
115 
116     return -1;
117 }
118 
119 /**
120  * rga_version_table_get_current_index() - Find the current version index in bind_table.
121  *
122  * @param version
123  * @param table
124  * @param table_size
125  *
126  * @returns if return value >= 0, then index is found, otherwise, the query fails.
127  */
rga_version_table_get_current_index(rga_version_t & version,const rga_version_bind_table_entry_t * table,int table_size)128 int rga_version_table_get_current_index(rga_version_t &version, const rga_version_bind_table_entry_t *table, int table_size) {
129     int index = -1;
130 
131     for (int i = (table_size - 1); i >= 0; i--) {
132         if (rga_version_compare(version, table[i].current) >= 0) {
133             if (i == (table_size - 1)) {
134                 index = i;
135                 break;
136             } else if (rga_version_compare(table[i + 1].current, version) > 0) {
137                 index = i;
138                 break;
139             }
140         }
141     }
142 
143     return index;
144 }
145 
146 /**
147  * rga_version_table_get_minimum_index() - Find the current version index in bind_table.
148  *
149  * @param version
150  * @param table
151  * @param table_size
152  *
153  * @returns if return value >= 0, then index is found, otherwise, the query fails.
154  */
rga_version_table_get_minimum_index(rga_version_t & version,const rga_version_bind_table_entry_t * table,int table_size)155 int rga_version_table_get_minimum_index(rga_version_t &version, const rga_version_bind_table_entry_t *table, int table_size) {
156     int index = -1;
157 
158     for (int i = (table_size - 1); i >= 0; i--) {
159         if (rga_version_compare(version, table[i].minimum) >= 0) {
160             if (i == (table_size - 1)) {
161                 index = i;
162                 break;
163             } else if (rga_version_compare(table[i + 1].minimum, version) > 0) {
164                 index = i;
165                 break;
166             }
167         }
168     }
169 
170     return index;
171 }
172 
173 /**
174  * rga_version_table_check_minimum_range() - Check if the minimum version is within the required range.
175  *
176  * @param version
177  * @param table
178  * @param index
179  *
180  * @returns
181  *   return value > 0, above range.
182  *   return value = 0, within range.
183  *   return value < 0, below range.
184  */
rga_version_table_check_minimum_range(rga_version_t & version,const rga_version_bind_table_entry_t * table,int table_size,int index)185 int rga_version_table_check_minimum_range(rga_version_t &version,
186                                           const rga_version_bind_table_entry_t *table,
187                                           int table_size, int index) {
188     if (rga_version_compare(version, table[index].minimum) >= 0) {
189         if (index == (table_size - 1))
190             return 0;
191 
192         if (rga_version_compare(version, table[index + 1].minimum) < 0)
193             return 0;
194         else
195             return 1;
196     } else {
197         return -1;
198     }
199 }
200 
rga_version_get_current_index_failed_default(rga_version_t & current,rga_version_t & minimum)201 static IM_STATUS rga_version_get_current_index_failed_default(rga_version_t &current, rga_version_t &minimum) {
202     UNUSED(current);
203     UNUSED(minimum);
204 
205     return IM_STATUS_ERROR_VERSION;
206 }
207 
rga_version_get_minimum_index_failed_default(rga_version_t & current,rga_version_t & minimum)208 static IM_STATUS rga_version_get_minimum_index_failed_default(rga_version_t &current, rga_version_t &minimum) {
209     UNUSED(current);
210     UNUSED(minimum);
211 
212     return IM_STATUS_ERROR_VERSION;
213 }
214 
rga_version_witnin_minimun_range_default(rga_version_t & current,rga_version_t & minimum)215 static IM_STATUS rga_version_witnin_minimun_range_default(rga_version_t &current, rga_version_t &minimum) {
216     UNUSED(current);
217     UNUSED(minimum);
218 
219     return IM_STATUS_SUCCESS;
220 }
221 
rga_version_above_minimun_range_default(rga_version_t & current,rga_version_t & minimum,const rga_version_bind_table_entry_t * least_version_table)222 static IM_STATUS rga_version_above_minimun_range_default(rga_version_t &current, rga_version_t &minimum, const rga_version_bind_table_entry_t *least_version_table) {
223     UNUSED(current);
224     UNUSED(minimum);
225     UNUSED(least_version_table);
226 
227     return IM_STATUS_ERROR_VERSION;
228 }
229 
rga_version_below_minimun_range_default(rga_version_t & current,rga_version_t & minimum,const rga_version_bind_table_entry_t * least_version_table)230 static IM_STATUS rga_version_below_minimun_range_default(rga_version_t &current, rga_version_t &minimum, const rga_version_bind_table_entry_t *least_version_table) {
231     UNUSED(current);
232     UNUSED(minimum);
233     UNUSED(least_version_table);
234 
235     return IM_STATUS_ERROR_VERSION;
236 }
237 
rga_version_get_current_index_failed_user_header(rga_version_t & user_version,rga_version_t & header_version)238 static IM_STATUS rga_version_get_current_index_failed_user_header(rga_version_t &user_version, rga_version_t &header_version) {
239     IM_LOGE("Failed to get the version binding table of librga, "
240             "current version: librga: %s, header: %s",
241             user_version.str, header_version.str);
242 
243     return IM_STATUS_ERROR_VERSION;
244 }
245 
rga_version_get_minimum_index_failed_user_header(rga_version_t & user_version,rga_version_t & header_version)246 static IM_STATUS rga_version_get_minimum_index_failed_user_header(rga_version_t &user_version, rga_version_t &header_version) {
247     IM_LOGE("Failed to get the version binding table of header file, "
248             "current version: librga: %s, header: %s",
249             user_version.str, header_version.str);
250 
251     return IM_STATUS_ERROR_VERSION;
252 }
253 
rga_version_above_minimun_range_user_header(rga_version_t & user_version,rga_version_t & header_version,const rga_version_bind_table_entry_t * least_version_table)254 static IM_STATUS rga_version_above_minimun_range_user_header(rga_version_t &user_version, rga_version_t &header_version, const rga_version_bind_table_entry_t *least_version_table) {
255     IM_LOGE("The current referenced header_version is %s, but the running librga's version(%s) is too old, "
256             "The librga must to be updated to version %s at least. "
257             "You can try to update the SDK or update librga.so and header files "
258             "through github(https://github.com/airockchip/librga/). ",
259             header_version.str, user_version.str,
260             least_version_table->current.str);
261 
262     return IM_STATUS_ERROR_VERSION;
263 }
264 
rga_version_below_minimun_range_user_header(rga_version_t & user_version,rga_version_t & header_version,const rga_version_bind_table_entry_t * least_version_table)265 static IM_STATUS rga_version_below_minimun_range_user_header(rga_version_t &user_version, rga_version_t &header_version, const rga_version_bind_table_entry_t *least_version_table) {
266     IM_LOGE("The current librga.so's verison is %s, but the referenced header_version(%s) is too old, "
267             "it is recommended to update the librga's header_version to %s and above."
268             "You can try to update the SDK or update librga.so and header files "
269             "through github(https://github.com/airockchip/librga/)",
270             user_version.str, header_version.str,
271             least_version_table->minimum.str);
272 
273     return IM_STATUS_ERROR_VERSION;
274 }
275 
rga_version_get_current_index_faile_user_driver(rga_version_t & user_version,rga_version_t & driver_version)276 static IM_STATUS rga_version_get_current_index_faile_user_driver(rga_version_t &user_version, rga_version_t &driver_version) {
277     IM_LOGE("Failed to get the version binding table of librga, "
278             "current version: librga: %s, driver: %s",
279             user_version.str, driver_version.str);
280 
281     return IM_STATUS_ERROR_VERSION;
282 }
283 
rga_version_get_minimum_index_failed_user_driver(rga_version_t & user_version,rga_version_t & driver_version)284 static IM_STATUS rga_version_get_minimum_index_failed_user_driver(rga_version_t &user_version, rga_version_t &driver_version) {
285     IM_LOGE("Failed to get the version binding table of rga_driver, "
286             "current version: librga: %s, driver: %s",
287             user_version.str, driver_version.str);
288 
289     return IM_STATUS_ERROR_VERSION;
290 }
291 
rga_version_above_minimun_range_user_driver(rga_version_t & user_version,rga_version_t & driver_version,const rga_version_bind_table_entry_t * least_version_table)292 static IM_STATUS rga_version_above_minimun_range_user_driver(rga_version_t &user_version, rga_version_t &driver_version, const rga_version_bind_table_entry_t *least_version_table) {
293     IM_LOGE("The librga must to be updated to version %s at least. "
294             "You can try to update the SDK or update librga.so and header files "
295             "through github(https://github.com/airockchip/librga/). "
296             "current version: librga %s, driver %s.",
297             least_version_table->current.str,
298             user_version.str, driver_version.str);
299 
300     return IM_STATUS_ERROR_VERSION;
301 }
302 
rga_version_below_minimun_range_user_driver(rga_version_t & user_version,rga_version_t & driver_version,const rga_version_bind_table_entry_t * least_version_table)303 static IM_STATUS rga_version_below_minimun_range_user_driver(rga_version_t &user_version, rga_version_t &driver_version, const rga_version_bind_table_entry_t *least_version_table) {
304     IM_LOGE("The driver may be compatible, "
305             "but it is best to update the driver to version %s. "
306             "You can try to update the SDK or update the "
307             "<SDK>/kernel/drivers/video/rockchip/rga3 directory individually. "
308             "current version: librga %s, driver %s.",
309             least_version_table->minimum.str,
310             user_version.str, driver_version.str);
311 
312     return IM_STATUS_ERROR_VERSION;
313 }
314 
315 static const rga_version_check_ops_t rga_version_check_user_header_ops {
316     .get_current_index_failed = rga_version_get_current_index_failed_user_header,
317     .get_minimum_index_failed = rga_version_get_minimum_index_failed_user_header,
318     .witnin_minimun_range = rga_version_witnin_minimun_range_default,
319     .above_minimun_range = rga_version_above_minimun_range_user_header,
320     .below_minimun_range = rga_version_below_minimun_range_user_header,
321 };
322 
323 static const rga_version_check_ops_t rga_version_check_user_driver_ops {
324     .get_current_index_failed = rga_version_get_current_index_faile_user_driver,
325     .get_minimum_index_failed = rga_version_get_minimum_index_failed_user_driver,
326     .witnin_minimun_range = rga_version_witnin_minimun_range_default,
327     .above_minimun_range = rga_version_above_minimun_range_user_driver,
328     .below_minimun_range = rga_version_below_minimun_range_user_driver,
329 };
330 
rga_version_check(rga_version_t & current_version,rga_version_t & minimum_version,const rga_version_bind_table_entry_t * table,int table_size,const rga_version_check_ops_t * ops)331 static int rga_version_check(rga_version_t &current_version, rga_version_t &minimum_version,
332                              const rga_version_bind_table_entry_t *table, int table_size,
333                              const rga_version_check_ops_t *ops) {
334     int ret;
335     int current_bind_index, least_index;
336 
337     current_bind_index = rga_version_table_get_current_index(current_version, table, table_size);
338     if (current_bind_index < 0)
339         return ops->get_current_index_failed ?
340                ops->get_current_index_failed(current_version, minimum_version) :
341                rga_version_get_current_index_failed_default(current_version, minimum_version);
342 
343     switch (rga_version_table_check_minimum_range(minimum_version, table, table_size, current_bind_index)) {
344         case 0:
345             ops->witnin_minimun_range ?
346                 ops->witnin_minimun_range(current_version, minimum_version) :
347                 rga_version_witnin_minimun_range_default(current_version, minimum_version);
348             return 0;
349 
350         case -1:
351             ops->below_minimun_range ?
352                 ops->below_minimun_range(current_version, minimum_version, &(table[current_bind_index])) :
353                 rga_version_below_minimun_range_default(current_version, minimum_version, &(table[current_bind_index]));
354             return -1;
355 
356         case 1:
357             least_index = rga_version_table_get_minimum_index(minimum_version, table, table_size);
358             if (least_index < 0) {
359                 ops->get_minimum_index_failed ?
360                     ops->get_minimum_index_failed(current_version, minimum_version) :
361                     rga_version_get_minimum_index_failed_default(current_version, minimum_version);
362                 return 1;
363             }
364 
365             ops->above_minimun_range ?
366                 ops->above_minimun_range(current_version, minimum_version, &(table[least_index])) :
367                 rga_version_above_minimun_range_default(current_version, minimum_version, &(table[least_index]));
368             return 1;
369 
370         default:
371             IM_LOGE("This shouldn't happen!");
372             return IM_STATUS_FAILED;
373     }
374 }
375 
rga_yuv_legality_check(const char * name,rga_buffer_t info,im_rect rect)376 static IM_STATUS rga_yuv_legality_check(const char *name, rga_buffer_t info, im_rect rect) {
377     if ((info.wstride % 2) || (info.hstride % 2) ||
378         (info.width % 2)  || (info.height % 2) ||
379         (rect.x % 2) || (rect.y % 2) ||
380         (rect.width % 2) || (rect.height % 2)) {
381         IM_LOGW("%s, Error yuv not align to 2, rect[x,y,w,h] = [%d, %d, %d, %d], "
382                 "wstride = %d, hstride = %d, format = 0x%x(%s)",
383                 name, rect.x, rect.y, info.width, info.height, info.wstride, info.hstride,
384                 info.format, translate_format_str(info.format));
385         return IM_STATUS_INVALID_PARAM;
386     }
387 
388     return IM_STATUS_SUCCESS;
389 }
390 
rga_is_buffer_valid(rga_buffer_t buf)391 bool rga_is_buffer_valid(rga_buffer_t buf) {
392     return (buf.phy_addr != NULL || buf.vir_addr != NULL || buf.fd > 0 || buf.handle > 0);
393 }
394 
rga_is_rect_valid(im_rect rect)395 bool rga_is_rect_valid(im_rect rect) {
396     return (rect.x > 0 || rect.y > 0 || (rect.width > 0 && rect.height > 0));
397 }
398 
empty_structure(rga_buffer_t * src,rga_buffer_t * dst,rga_buffer_t * pat,im_rect * srect,im_rect * drect,im_rect * prect,im_opt_t * opt)399 void empty_structure(rga_buffer_t *src, rga_buffer_t *dst, rga_buffer_t *pat,
400                      im_rect *srect, im_rect *drect, im_rect *prect, im_opt_t *opt) {
401     if (src != NULL)
402         memset(src, 0, sizeof(*src));
403     if (dst != NULL)
404         memset(dst, 0, sizeof(*dst));
405     if (pat != NULL)
406         memset(pat, 0, sizeof(*pat));
407     if (srect != NULL)
408         memset(srect, 0, sizeof(*srect));
409     if (drect != NULL)
410         memset(drect, 0, sizeof(*drect));
411     if (prect != NULL)
412         memset(prect, 0, sizeof(*prect));
413     if (opt != NULL)
414         memset(opt, 0, sizeof(*opt));
415 }
416 
rga_set_buffer_info(rga_buffer_t dst,rga_info_t * dstinfo)417 IM_STATUS rga_set_buffer_info(rga_buffer_t dst, rga_info_t* dstinfo) {
418     if(NULL == dstinfo) {
419         IM_LOGE("Invaild dstinfo, dst structure address is NULL!");
420         return IM_STATUS_INVALID_PARAM;
421     }
422 
423     if (dst.handle > 0) {
424         dstinfo->handle = dst.handle;
425     } else if(dst.phy_addr != NULL) {
426         dstinfo->phyAddr= dst.phy_addr;
427     } else if(dst.fd > 0) {
428         dstinfo->fd = dst.fd;
429         dstinfo->mmuFlag = 1;
430     } else if(dst.vir_addr != NULL) {
431         dstinfo->virAddr = dst.vir_addr;
432         dstinfo->mmuFlag = 1;
433     } else {
434         IM_LOGE("Invaild dst buffer, no address available in dst buffer, phy_addr = %ld, fd = %d, vir_addr = %ld, handle = %d",
435                 (unsigned long)dst.phy_addr, dst.fd, (unsigned long)dst.vir_addr, dst.handle);
436         return IM_STATUS_INVALID_PARAM;
437     }
438 
439     return IM_STATUS_SUCCESS;
440 }
441 
rga_set_buffer_info(const rga_buffer_t src,rga_buffer_t dst,rga_info_t * srcinfo,rga_info_t * dstinfo)442 IM_STATUS rga_set_buffer_info(const rga_buffer_t src, rga_buffer_t dst, rga_info_t* srcinfo, rga_info_t* dstinfo) {
443     if(NULL == srcinfo) {
444         IM_LOGE("Invaild srcinfo, src structure address is NULL.");
445         return IM_STATUS_INVALID_PARAM;
446     }
447     if(NULL == dstinfo) {
448         IM_LOGE("Invaild dstinfo, dst structure address is NULL.");
449         return IM_STATUS_INVALID_PARAM;
450     }
451 
452     if (src.handle > 0) {
453         srcinfo->handle = src.handle;
454     } else if(src.phy_addr != NULL) {
455         srcinfo->phyAddr = src.phy_addr;
456     } else if(src.fd > 0) {
457         srcinfo->fd = src.fd;
458         srcinfo->mmuFlag = 1;
459     } else if(src.vir_addr != NULL) {
460         srcinfo->virAddr = src.vir_addr;
461         srcinfo->mmuFlag = 1;
462     } else {
463         IM_LOGE("Invaild src buffer, no address available in src buffer, phy_addr = %ld, fd = %d, vir_addr = %ld, handle = %d",
464                 (unsigned long)src.phy_addr, src.fd, (unsigned long)src.vir_addr, src.handle);
465         return IM_STATUS_INVALID_PARAM;
466     }
467 
468     if (dst.handle > 0) {
469         dstinfo->handle = dst.handle;
470     } else if(dst.phy_addr != NULL) {
471         dstinfo->phyAddr= dst.phy_addr;
472     } else if(dst.fd > 0) {
473         dstinfo->fd = dst.fd;
474         dstinfo->mmuFlag = 1;
475     } else if(dst.vir_addr != NULL) {
476         dstinfo->virAddr = dst.vir_addr;
477         dstinfo->mmuFlag = 1;
478     } else {
479         IM_LOGE("Invaild dst buffer, no address available in dst buffer, phy_addr = %ld, fd = %d, vir_addr = %ld, handle = %d",
480                 (unsigned long)dst.phy_addr, dst.fd, (unsigned long)dst.vir_addr, dst.handle);
481         return IM_STATUS_INVALID_PARAM;
482     }
483 
484     return IM_STATUS_SUCCESS;
485 }
486 
rga_get_info(rga_info_table_entry * return_table)487 IM_STATUS rga_get_info(rga_info_table_entry *return_table) {
488     int ret;
489     int  rga_version = 0;
490     rga_info_table_entry merge_table;
491 
492     ret = rga_get_context();
493     if (ret != IM_STATUS_SUCCESS)
494         return (IM_STATUS)ret;
495 
496     memset(&merge_table, 0x0, sizeof(merge_table));
497 
498     for (uint32_t i = 0; i < rgaCtx->mHwVersions.size; i++) {
499         if (rgaCtx->mHwVersions.version[i].major == 2 &&
500             rgaCtx->mHwVersions.version[i].minor == 0) {
501             if (rgaCtx->mHwVersions.version[i].revision == 0) {
502                 rga_version = IM_RGA_HW_VERSION_RGA_2_INDEX;
503                 memcpy(&merge_table, &hw_info_table[rga_version], sizeof(merge_table));
504             } else {
505                 goto TRY_TO_COMPATIBLE;
506             }
507         } else if (rgaCtx->mHwVersions.version[i].major == 3 &&
508                    rgaCtx->mHwVersions.version[i].minor == 0) {
509             switch (rgaCtx->mHwVersions.version[i].revision) {
510                 case 0x16445 :
511                     rga_version = IM_RGA_HW_VERSION_RGA_2_INDEX;
512                     memcpy(&merge_table, &hw_info_table[rga_version], sizeof(merge_table));
513                     break;
514                 case 0x22245 :
515                     rga_version = IM_RGA_HW_VERSION_RGA_2_ENHANCE_INDEX;
516                     memcpy(&merge_table, &hw_info_table[rga_version], sizeof(merge_table));
517                     break;
518                 case 0x76831 :
519                     rga_version = IM_RGA_HW_VERSION_RGA_3_INDEX;
520                     memcpy(&merge_table, &hw_info_table[rga_version], sizeof(merge_table));
521                     break;
522                 default :
523                     goto TRY_TO_COMPATIBLE;
524             }
525         } else if (rgaCtx->mHwVersions.version[i].major == 3 &&
526                    rgaCtx->mHwVersions.version[i].minor == 2) {
527             switch (rgaCtx->mHwVersions.version[i].revision) {
528                 case 0x18218 :
529                     rga_version = IM_RGA_HW_VERSION_RGA_2_ENHANCE_INDEX;
530                     memcpy(&merge_table, &hw_info_table[rga_version], sizeof(merge_table));
531 
532                     merge_table.feature |= IM_RGA_SUPPORT_FEATURE_ROP;
533                     break;
534                 case 0x56726 :
535                 case 0x63318 :
536                     rga_version = IM_RGA_HW_VERSION_RGA_2_ENHANCE_INDEX;
537                     memcpy(&merge_table, &hw_info_table[rga_version], sizeof(merge_table));
538 
539                     merge_table.input_format |= IM_RGA_SUPPORT_FORMAT_YUYV_422 |
540                                                  IM_RGA_SUPPORT_FORMAT_YUV_400;
541                     merge_table.output_format |= IM_RGA_SUPPORT_FORMAT_YUV_400 |
542                                                   IM_RGA_SUPPORT_FORMAT_Y4;
543                     merge_table.feature |= IM_RGA_SUPPORT_FEATURE_QUANTIZE |
544                                             IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC |
545                                             IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC;
546                     break;
547                 default :
548                     goto TRY_TO_COMPATIBLE;
549             }
550         } else if (rgaCtx->mHwVersions.version[i].major == 3 &&
551                    rgaCtx->mHwVersions.version[i].minor == 3) {
552             switch (rgaCtx->mHwVersions.version[i].revision) {
553                 case 0x87975:
554                     rga_version = IM_RGA_HW_VERSION_RGA_2_ENHANCE_INDEX;
555                     memcpy(&merge_table, &hw_info_table[rga_version], sizeof(merge_table));
556 
557                     merge_table.input_format |= IM_RGA_SUPPORT_FORMAT_YUYV_422 |
558                                                 IM_RGA_SUPPORT_FORMAT_YUV_400 |
559                                                 IM_RGA_SUPPORT_FORMAT_RGBA2BPP;
560                     merge_table.output_format |= IM_RGA_SUPPORT_FORMAT_YUV_400 |
561                                                  IM_RGA_SUPPORT_FORMAT_Y4;
562                     merge_table.feature |= IM_RGA_SUPPORT_FEATURE_QUANTIZE |
563                                            IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC |
564                                            IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC |
565                                            IM_RGA_SUPPORT_FEATURE_MOSAIC |
566                                            IM_RGA_SUPPORT_FEATURE_OSD |
567                                            IM_RGA_SUPPORT_FEATURE_PRE_INTR;
568                     break;
569                 default :
570                     goto TRY_TO_COMPATIBLE;
571             }
572         } else if (rgaCtx->mHwVersions.version[i].major == 3 &&
573                    rgaCtx->mHwVersions.version[i].minor == 6) {
574             switch (rgaCtx->mHwVersions.version[i].revision) {
575                 case 0x92812:
576                     rga_version = IM_RGA_HW_VERSION_RGA_2_ENHANCE_INDEX;
577                     memcpy(&merge_table, &hw_info_table[rga_version], sizeof(merge_table));
578 
579                     merge_table.input_format |= IM_RGA_SUPPORT_FORMAT_YUYV_422 |
580                                                 IM_RGA_SUPPORT_FORMAT_YUV_400 |
581                                                 IM_RGA_SUPPORT_FORMAT_RGBA2BPP;
582                     merge_table.output_format |= IM_RGA_SUPPORT_FORMAT_YUV_400 |
583                                                  IM_RGA_SUPPORT_FORMAT_Y4;
584                     merge_table.feature |= IM_RGA_SUPPORT_FEATURE_QUANTIZE |
585                                            IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC |
586                                            IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC |
587                                            IM_RGA_SUPPORT_FEATURE_MOSAIC |
588                                            IM_RGA_SUPPORT_FEATURE_OSD |
589                                            IM_RGA_SUPPORT_FEATURE_PRE_INTR;
590                     break;
591                 default :
592                     goto TRY_TO_COMPATIBLE;
593                 }
594         } else if (rgaCtx->mHwVersions.version[i].major == 3 &&
595                    rgaCtx->mHwVersions.version[i].minor == 7) {
596             switch (rgaCtx->mHwVersions.version[i].revision) {
597                 case 0x93215:
598                     rga_version = IM_RGA_HW_VERSION_RGA_2_ENHANCE_INDEX;
599                     memcpy(&merge_table, &hw_info_table[rga_version], sizeof(merge_table));
600 
601                     merge_table.input_format |= IM_RGA_SUPPORT_FORMAT_YUYV_422 |
602                                                 IM_RGA_SUPPORT_FORMAT_YUV_400 |
603                                                 IM_RGA_SUPPORT_FORMAT_RGBA2BPP;
604                     merge_table.output_format |= IM_RGA_SUPPORT_FORMAT_YUV_400 |
605                                                  IM_RGA_SUPPORT_FORMAT_Y4;
606                     merge_table.feature |= IM_RGA_SUPPORT_FEATURE_QUANTIZE |
607                                            IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC |
608                                            IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC |
609                                            IM_RGA_SUPPORT_FEATURE_MOSAIC |
610                                            IM_RGA_SUPPORT_FEATURE_OSD |
611                                            IM_RGA_SUPPORT_FEATURE_PRE_INTR;
612                     break;
613                 default :
614                     goto TRY_TO_COMPATIBLE;
615             }
616         } else if (rgaCtx->mHwVersions.version[i].major == 4 &&
617                    rgaCtx->mHwVersions.version[i].minor == 0) {
618             switch (rgaCtx->mHwVersions.version[i].revision) {
619                 case 0x18632 :
620                     rga_version = IM_RGA_HW_VERSION_RGA_2_LITE0_INDEX;
621                     memcpy(&merge_table, &hw_info_table[rga_version], sizeof(merge_table));
622                     break;
623                 case 0x23998 :
624                 case 0x28610 :
625                     rga_version = IM_RGA_HW_VERSION_RGA_2_LITE1_INDEX;
626                     memcpy(&merge_table, &hw_info_table[rga_version], sizeof(merge_table));
627 
628                     merge_table.feature |= IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC;
629                     break;
630                 default :
631                     goto TRY_TO_COMPATIBLE;
632             }
633         } else if (rgaCtx->mHwVersions.version[i].major == 42 &&
634                    rgaCtx->mHwVersions.version[i].minor == 0) {
635             if (rgaCtx->mHwVersions.version[i].revision == 0x17760) {
636                 rga_version = IM_RGA_HW_VERSION_RGA_2_LITE1_INDEX;
637                 memcpy(&merge_table, &hw_info_table[rga_version], sizeof(merge_table));
638             } else {
639                 goto TRY_TO_COMPATIBLE;
640             }
641         } else {
642             goto TRY_TO_COMPATIBLE;
643         }
644 
645         rga_support_info_merge_table(return_table, &merge_table);
646     }
647 
648     return IM_STATUS_SUCCESS;
649 
650 TRY_TO_COMPATIBLE:
651     if (strncmp((char *)rgaCtx->mHwVersions.version[0].str, "1.3", 3) == 0)
652         rga_version = IM_RGA_HW_VERSION_RGA_1_INDEX;
653     else if (strncmp((char *)rgaCtx->mHwVersions.version[0].str, "1.6", 3) == 0)
654         rga_version = IM_RGA_HW_VERSION_RGA_1_PLUS_INDEX;
655     /*3288 vesion is 2.00*/
656     else if (strncmp((char *)rgaCtx->mHwVersions.version[0].str, "2.00", 4) == 0)
657         rga_version = IM_RGA_HW_VERSION_RGA_2_INDEX;
658     /*3288w version is 3.00*/
659     else if (strncmp((char *)rgaCtx->mHwVersions.version[0].str, "3.00", 4) == 0)
660         rga_version = IM_RGA_HW_VERSION_RGA_2_INDEX;
661     else if (strncmp((char *)rgaCtx->mHwVersions.version[0].str, "3.02", 4) == 0)
662         rga_version = IM_RGA_HW_VERSION_RGA_2_ENHANCE_INDEX;
663     else if (strncmp((char *)rgaCtx->mHwVersions.version[0].str, "4.00", 4) == 0)
664         rga_version = IM_RGA_HW_VERSION_RGA_2_LITE0_INDEX;
665     /*The version number of lite1 cannot be obtained temporarily.*/
666     else if (strncmp((char *)rgaCtx->mHwVersions.version[0].str, "4.00", 4) == 0)
667         rga_version = IM_RGA_HW_VERSION_RGA_2_LITE1_INDEX;
668     else
669         rga_version = IM_RGA_HW_VERSION_RGA_V_ERR_INDEX;
670 
671     memcpy(return_table, &hw_info_table[rga_version], sizeof(rga_info_table_entry));
672 
673     if (rga_version == IM_RGA_HW_VERSION_RGA_V_ERR_INDEX) {
674         IM_LOGE("Can not get the correct RGA version, please check the driver, version=%s\n",
675                 rgaCtx->mHwVersions.version[0].str);
676         return IM_STATUS_FAILED;
677     }
678 
679     return IM_STATUS_SUCCESS;
680 }
681 
rga_check_header(rga_version_t header_version)682 IM_STATUS rga_check_header(rga_version_t header_version) {
683     int ret;
684     int table_size = sizeof(user_header_bind_table) / sizeof(rga_version_bind_table_entry_t);
685     rga_version_t user_version = RGA_SET_CURRENT_API_VERSION;
686 
687     ret = rga_version_check(user_version, header_version,
688                             user_header_bind_table, table_size,
689                             &rga_version_check_user_header_ops);
690     switch (ret) {
691         case 0:
692             return IM_STATUS_SUCCESS;
693         case 1:
694         case -1:
695         default:
696             return IM_STATUS_ERROR_VERSION;
697     }
698 }
699 
rga_check_driver(rga_version_t & driver_version)700 IM_STATUS rga_check_driver(rga_version_t &driver_version) {
701     int ret;
702     int table_size = sizeof(user_driver_bind_table) / sizeof(rga_version_bind_table_entry_t);
703     rga_version_t user_version = RGA_SET_CURRENT_API_VERSION;
704 
705     ret =  rga_version_check(user_version, driver_version,
706                              user_driver_bind_table, table_size,
707                              &rga_version_check_user_driver_ops);
708     switch (ret) {
709         case 0:
710         case -1:
711             return IM_STATUS_SUCCESS;
712         case 1:
713         default:
714             return IM_STATUS_ERROR_VERSION;
715     }
716 }
717 
rga_check_info(const char * name,const rga_buffer_t info,const im_rect rect,int resolution_usage)718 IM_STATUS rga_check_info(const char *name, const rga_buffer_t info, const im_rect rect, int resolution_usage) {
719     /**************** src/dst judgment ****************/
720     if (info.width <= 0 || info.height <= 0 || info.format < 0) {
721         IM_LOGW("Illegal %s, the parameter cannot be negative or 0, width = %d, height = %d, format = 0x%x(%s)",
722                 name, info.width, info.height, info.format, translate_format_str(info.format));
723         return IM_STATUS_ILLEGAL_PARAM;
724     }
725 
726     if (info.width < 2 || info.height < 2) {
727         IM_LOGW("Hardware limitation %s, unsupported operation of images smaller than 2 pixels, "
728                 "width = %d, height = %d",
729                 name, info.width, info.height);
730         return IM_STATUS_ILLEGAL_PARAM;
731     }
732 
733     if (info.wstride < info.width || info.hstride < info.height) {
734         IM_LOGW("Invaild %s, Virtual width or height is less than actual width and height, "
735                 "wstride = %d, width = %d, hstride = %d, height = %d",
736                 name, info.wstride, info.width, info.hstride, info.height);
737         return IM_STATUS_INVALID_PARAM;
738     }
739 
740     /**************** rect judgment ****************/
741     if (rect.width < 0 || rect.height < 0 || rect.x < 0 || rect.y < 0) {
742         IM_LOGW("Illegal %s rect, the parameter cannot be negative, rect[x,y,w,h] = [%d, %d, %d, %d]",
743                 name, rect.x, rect.y, rect.width, rect.height);
744         return IM_STATUS_ILLEGAL_PARAM;
745     }
746 
747     if ((rect.width > 0  && rect.width < 2) || (rect.height > 0 && rect.height < 2) ||
748         (rect.x > 0 && rect.x < 2)          || (rect.y > 0 && rect.y < 2)) {
749         IM_LOGW("Hardware limitation %s rect, unsupported operation of images smaller than 2 pixels, "
750                 "rect[x,y,w,h] = [%d, %d, %d, %d]",
751                 name, rect.x, rect.y, rect.width, rect.height);
752         return IM_STATUS_INVALID_PARAM;
753     }
754 
755     if ((rect.width + rect.x > info.wstride) || (rect.height + rect.y > info.hstride)) {
756         IM_LOGW("Invaild %s rect, the sum of width and height of rect needs to be less than wstride or hstride, "
757                 "rect[x,y,w,h] = [%d, %d, %d, %d], wstride = %d, hstride = %d",
758                 name, rect.x, rect.y, rect.width, rect.height, info.wstride, info.hstride);
759         return IM_STATUS_INVALID_PARAM;
760     }
761 
762     /**************** resolution check ****************/
763     if (info.width > resolution_usage ||
764         info.height > resolution_usage) {
765         IM_LOGW("Unsupported %s to input resolution more than %d, width = %d, height = %d",
766                 name, resolution_usage, info.width, info.height);
767         return IM_STATUS_NOT_SUPPORTED;
768     } else if ((rect.width > 0 && rect.width > resolution_usage) ||
769                (rect.height > 0 && rect.height > resolution_usage)) {
770         IM_LOGW("Unsupported %s rect to output resolution more than %d, rect[x,y,w,h] = [%d, %d, %d, %d]",
771                 name, resolution_usage, rect.x, rect.y, rect.width, rect.height);
772         return IM_STATUS_NOT_SUPPORTED;
773     }
774 
775     return IM_STATUS_NOERROR;
776 }
777 
rga_check_limit(rga_buffer_t src,rga_buffer_t dst,int scale_usage,int mode_usage)778 IM_STATUS rga_check_limit(rga_buffer_t src, rga_buffer_t dst, int scale_usage, int mode_usage) {
779     int src_width = 0, src_height = 0;
780     int dst_width = 0, dst_height = 0;
781 
782     src_width = src.width;
783     src_height = src.height;
784 
785     if (mode_usage & IM_HAL_TRANSFORM_ROT_270 || mode_usage & IM_HAL_TRANSFORM_ROT_90) {
786         dst_width = dst.height;
787         dst_height = dst.width;
788     } else {
789         dst_width = dst.width;
790         dst_height = dst.height;
791     }
792     if (((src_width >> (int)(log(scale_usage)/log(2))) > dst_width) ||
793        ((src_height >> (int)(log(scale_usage)/log(2))) > dst_height)) {
794         IM_LOGW("Unsupported to scaling less than 1/%d ~ %d times, src[w,h] = [%d, %d], dst[w,h] = [%d, %d]",
795                 scale_usage, scale_usage, src.width, src.height, dst.width, dst.height);
796         return IM_STATUS_NOT_SUPPORTED;
797     }
798     if (((dst_width >> (int)(log(scale_usage)/log(2))) > src_width) ||
799        ((dst_height >> (int)(log(scale_usage)/log(2))) > src_height)) {
800         IM_LOGW("Unsupported to scaling more than 1/%d ~ %d times, src[w,h] = [%d, %d], dst[w,h] = [%d, %d]",
801                 scale_usage, scale_usage, src.width, src.height, dst.width, dst.height);
802         return IM_STATUS_NOT_SUPPORTED;
803     }
804 
805     return IM_STATUS_NOERROR;
806 }
807 
rga_check_format(const char * name,rga_buffer_t info,im_rect rect,int format_usage,int mode_usgae)808 IM_STATUS rga_check_format(const char *name, rga_buffer_t info, im_rect rect, int format_usage, int mode_usgae) {
809     IM_STATUS ret;
810     int format = info.format;
811 
812     if (format == RK_FORMAT_RGBA_8888 || format == RK_FORMAT_BGRA_8888 ||
813         format == RK_FORMAT_RGBX_8888 || format == RK_FORMAT_BGRX_8888 ||
814         format == RK_FORMAT_ARGB_8888 || format == RK_FORMAT_ABGR_8888 ||
815         format == RK_FORMAT_XRGB_8888 || format == RK_FORMAT_XBGR_8888 ||
816         format == RK_FORMAT_RGB_888   || format == RK_FORMAT_BGR_888   ||
817         format == RK_FORMAT_RGB_565   || format == RK_FORMAT_BGR_565) {
818         if (~format_usage & IM_RGA_SUPPORT_FORMAT_RGB) {
819             IM_LOGW("%s unsupported RGB format, format = 0x%x(%s)\n%s",
820                     name, info.format, translate_format_str(info.format),
821                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
822             return IM_STATUS_NOT_SUPPORTED;
823         }
824     } else if (format == RK_FORMAT_RGBA_4444 || format == RK_FORMAT_BGRA_4444 ||
825                format == RK_FORMAT_RGBA_5551 || format == RK_FORMAT_BGRA_5551 ||
826                format == RK_FORMAT_ARGB_4444 || format == RK_FORMAT_ABGR_4444 ||
827                format == RK_FORMAT_ARGB_5551 || format == RK_FORMAT_ABGR_5551) {
828         if (~format_usage & IM_RGA_SUPPORT_FORMAT_RGB_OTHER) {
829             IM_LOGW("%s unsupported RGBA 4444/5551 format, format = 0x%x(%s)\n%s",
830                     name, info.format, translate_format_str(info.format),
831                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
832             return IM_STATUS_NOT_SUPPORTED;
833         }
834     } else if (format == RK_FORMAT_BPP1 || format == RK_FORMAT_BPP2 ||
835                format == RK_FORMAT_BPP4 || format == RK_FORMAT_BPP8) {
836         if ((~format_usage & IM_RGA_SUPPORT_FORMAT_BPP) && !(mode_usgae & IM_COLOR_PALETTE)) {
837             IM_LOGW("%s unsupported BPP format, format = 0x%x(%s)\n%s",
838                     name, info.format, translate_format_str(info.format),
839                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
840             return IM_STATUS_NOT_SUPPORTED;
841         }
842     } else if (format == RK_FORMAT_YCrCb_420_SP || format == RK_FORMAT_YCbCr_420_SP) {
843         if (~format_usage & IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_8_BIT) {
844             IM_LOGW("%s unsupported YUV420 semi-planner 8bit format, format = 0x%x(%s)\n%s",
845                     name, info.format, translate_format_str(info.format),
846                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
847             return IM_STATUS_NOT_SUPPORTED;
848         }
849 
850         ret = rga_yuv_legality_check(name, info, rect);
851         if (ret != IM_STATUS_SUCCESS)
852             return ret;
853     } else if (format == RK_FORMAT_YCrCb_420_P  || format == RK_FORMAT_YCbCr_420_P) {
854         if (~format_usage & IM_RGA_SUPPORT_FORMAT_YUV_420_PLANNER_8_BIT) {
855             IM_LOGW("%s unsupported YUV420 planner 8bit format, format = 0x%x(%s)\n%s",
856                     name, info.format, translate_format_str(info.format),
857                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
858             return IM_STATUS_NOT_SUPPORTED;
859         }
860 
861         ret = rga_yuv_legality_check(name, info, rect);
862         if (ret != IM_STATUS_SUCCESS)
863             return ret;
864     } else if (format == RK_FORMAT_YCrCb_422_SP || format == RK_FORMAT_YCbCr_422_SP) {
865         if (~format_usage & IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_8_BIT) {
866             IM_LOGW("%s unsupported YUV422 semi-planner 8bit format, format = 0x%x(%s)\n%s",
867                     name, info.format, translate_format_str(info.format),
868                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
869             return IM_STATUS_NOT_SUPPORTED;
870         }
871 
872         ret = rga_yuv_legality_check(name, info, rect);
873         if (ret != IM_STATUS_SUCCESS)
874             return ret;
875     } else if (format == RK_FORMAT_YCrCb_422_P  || format == RK_FORMAT_YCbCr_422_P) {
876         if (~format_usage & IM_RGA_SUPPORT_FORMAT_YUV_422_PLANNER_8_BIT) {
877             IM_LOGW("%s unsupported YUV422 planner 8bit format, format = 0x%x(%s)\n%s",
878                     name, info.format, translate_format_str(info.format),
879                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
880             return IM_STATUS_NOT_SUPPORTED;
881         }
882 
883         ret = rga_yuv_legality_check(name, info, rect);
884         if (ret != IM_STATUS_SUCCESS)
885             return ret;
886     } else if (format == RK_FORMAT_YCrCb_420_SP_10B || format == RK_FORMAT_YCbCr_420_SP_10B) {
887         if (~format_usage & IM_RGA_SUPPORT_FORMAT_YUV_420_SEMI_PLANNER_10_BIT) {
888             IM_LOGW("%s unsupported YUV420 semi-planner 10bit format, format = 0x%x(%s)\n%s",
889                     name, info.format, translate_format_str(info.format),
890                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
891             return IM_STATUS_NOT_SUPPORTED;
892         }
893 
894         ret = rga_yuv_legality_check(name, info, rect);
895         if (ret != IM_STATUS_SUCCESS)
896             return ret;
897         IM_LOGW("If it is an RK encoder output, it needs to be aligned with an odd multiple of 256.\n");
898     } else if (format == RK_FORMAT_YCrCb_422_10b_SP || format == RK_FORMAT_YCbCr_422_10b_SP) {
899         if (~format_usage & IM_RGA_SUPPORT_FORMAT_YUV_422_SEMI_PLANNER_10_BIT) {
900             IM_LOGW("%s unsupported YUV422 semi-planner 10bit format, format = 0x%x(%s)\n%s",
901                     name, info.format, translate_format_str(info.format),
902                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
903             return IM_STATUS_NOT_SUPPORTED;
904         }
905 
906         ret = rga_yuv_legality_check(name, info, rect);
907         if (ret != IM_STATUS_SUCCESS)
908             return ret;
909         IM_LOGW("If it is an RK encoder output, it needs to be aligned with an odd multiple of 256.\n");
910     } else if (format == RK_FORMAT_YUYV_420 || format == RK_FORMAT_YVYU_420 ||
911                format == RK_FORMAT_UYVY_420 || format == RK_FORMAT_VYUY_420) {
912         if (~format_usage & IM_RGA_SUPPORT_FORMAT_YUYV_420) {
913             IM_LOGW("%s unsupported YUYV format, format = 0x%x(%s)\n%s",
914                     name, info.format, translate_format_str(info.format),
915                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
916             return IM_STATUS_NOT_SUPPORTED;
917         }
918 
919         ret = rga_yuv_legality_check(name, info, rect);
920         if (ret != IM_STATUS_SUCCESS)
921             return ret;
922     } else if (format == RK_FORMAT_YUYV_422 || format == RK_FORMAT_YVYU_422 ||
923                format == RK_FORMAT_UYVY_422 || format == RK_FORMAT_VYUY_422) {
924         if (~format_usage & IM_RGA_SUPPORT_FORMAT_YUYV_422) {
925             IM_LOGW("%s unsupported YUYV format, format = 0x%x(%s)\n%s",
926                     name, info.format, translate_format_str(info.format),
927                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
928             return IM_STATUS_NOT_SUPPORTED;
929         }
930 
931         ret = rga_yuv_legality_check(name, info, rect);
932         if (ret != IM_STATUS_SUCCESS)
933             return ret;
934     } else if (format == RK_FORMAT_YCbCr_400) {
935         if (~format_usage & IM_RGA_SUPPORT_FORMAT_YUV_400) {
936             IM_LOGW("%s unsupported YUV400 format, format = 0x%x(%s)\n%s",
937                     name, info.format, translate_format_str(info.format),
938                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
939             return IM_STATUS_NOT_SUPPORTED;
940         }
941 
942         ret = rga_yuv_legality_check(name, info, rect);
943         if (ret != IM_STATUS_SUCCESS)
944             return ret;
945     } else if (format == RK_FORMAT_Y4) {
946         if (~format_usage & IM_RGA_SUPPORT_FORMAT_Y4) {
947             IM_LOGW("%s unsupported Y4/Y1 format, format = 0x%x(%s)\n%s",
948                     name, info.format, translate_format_str(info.format),
949                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
950             return IM_STATUS_NOT_SUPPORTED;
951         }
952 
953         ret = rga_yuv_legality_check(name, info, rect);
954         if (ret != IM_STATUS_SUCCESS)
955             return ret;
956     } else if (format == RK_FORMAT_RGBA2BPP) {
957         if (~format_usage & IM_RGA_SUPPORT_FORMAT_RGBA2BPP) {
958             IM_LOGW("%s unsupported rgba2bpp format, format = 0x%x(%s)\n%s",
959                     name, info.format, translate_format_str(info.format),
960                     querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
961             return IM_STATUS_NOT_SUPPORTED;
962         }
963     } else {
964         IM_LOGW("%s unsupported this format, format = 0x%x(%s)\n%s",
965                 name, info.format, translate_format_str(info.format),
966                 querystring((strcmp("dst", name) == 0) ? RGA_OUTPUT_FORMAT : RGA_INPUT_FORMAT));
967         return IM_STATUS_NOT_SUPPORTED;
968     }
969 
970     return IM_STATUS_NOERROR;
971 }
972 
rga_check_align(const char * name,rga_buffer_t info,int byte_stride,bool is_read)973 IM_STATUS rga_check_align(const char *name, rga_buffer_t info, int byte_stride, bool is_read) {
974     int bpp = 0;
975     int bit_stride, pixel_stride, align, gcd;
976 
977     /* data mode align */
978     switch (info.rd_mode) {
979         case IM_FBC_MODE:
980             if (info.wstride % 16) {
981                 IM_LOGE("%s FBC mode does not support width_stride[%d] is non-16 aligned\n",
982                         name, info.width);
983                 return IM_STATUS_NOT_SUPPORTED;
984             }
985 
986             if (info.hstride % 16) {
987                 IM_LOGE("%s FBC mode does not support height_stride[%d] is non-16 aligned\n",
988                         name, info.height);
989                 return IM_STATUS_NOT_SUPPORTED;
990             }
991             break;
992         case IM_TILE_MODE:
993             if (info.width % 8) {
994                 IM_LOGE("%s TILE8*8 mode does not support width[%d] is non-8 aligned\n",
995                         name, info.width);
996                 return IM_STATUS_NOT_SUPPORTED;
997             }
998 
999             if (info.height % 8) {
1000                 IM_LOGE("%s TILE8*8 mode does not support height[%d] is non-8 aligned\n",
1001                         name, info.height);
1002                 return IM_STATUS_NOT_SUPPORTED;
1003             }
1004 
1005             if (is_read) {
1006                 if (info.wstride % 16) {
1007                     IM_LOGE("%s TILE8*8 mode does not support input width_stride[%d] is non-16 aligned\n",
1008                             name, info.wstride);
1009                     return IM_STATUS_NOT_SUPPORTED;
1010                 }
1011 
1012                 if (info.hstride % 16) {
1013                     IM_LOGE("%s TILE8*8 mode does not support input height_stride[%d] is non-16 aligned\n",
1014                             name, info.hstride);
1015                     return IM_STATUS_NOT_SUPPORTED;
1016                 }
1017             }
1018             break;
1019         default:
1020             break;
1021     }
1022 
1023     pixel_stride = get_perPixel_stride_from_format(info.format);
1024 
1025     bit_stride = pixel_stride * info.wstride;
1026     if (bit_stride % (byte_stride * 8) == 0) {
1027         return IM_STATUS_NOERROR;
1028     } else {
1029         gcd = GET_GCD(pixel_stride, byte_stride * 8);
1030         align = GET_LCM(pixel_stride, byte_stride * 8, gcd) / pixel_stride;
1031         IM_LOGW("%s unsupport width stride %d, %s width stride should be %d aligned!",
1032                 name, info.wstride, translate_format_str(info.format), align);
1033         return IM_STATUS_NOT_SUPPORTED;
1034     }
1035 
1036     return IM_STATUS_NOERROR;
1037 }
1038 
rga_check_blend(rga_buffer_t src,rga_buffer_t pat,rga_buffer_t dst,int pat_enable,int mode_usage)1039 IM_STATUS rga_check_blend(rga_buffer_t src, rga_buffer_t pat, rga_buffer_t dst, int pat_enable, int mode_usage) {
1040     int src_fmt, pat_fmt, dst_fmt;
1041     bool src_isRGB, pat_isRGB, dst_isRGB;
1042 
1043     src_fmt = src.format;
1044     pat_fmt = pat.format;
1045     dst_fmt = dst.format;
1046 
1047     src_isRGB = NormalRgaIsRgbFormat(src_fmt);
1048     pat_isRGB = NormalRgaIsRgbFormat(pat_fmt);
1049     dst_isRGB = NormalRgaIsRgbFormat(dst_fmt);
1050 
1051     /**************** blend mode check ****************/
1052     switch (mode_usage & IM_ALPHA_BLEND_MASK) {
1053         case IM_ALPHA_BLEND_SRC :
1054         case IM_ALPHA_BLEND_DST :
1055             break;
1056         case IM_ALPHA_BLEND_SRC_OVER :
1057             if (!NormalRgaFormatHasAlpha(src_fmt)) {
1058                 IM_LOGW("Blend mode 'src_over' unsupported src format without alpha, "
1059                         "format[src,src1,dst] = [0x%x(%s), 0x%x(%s), 0x%x(%s)]",
1060                         src_fmt, translate_format_str(src_fmt),
1061                         pat_fmt, translate_format_str(pat_fmt),
1062                         dst_fmt, translate_format_str(dst_fmt));
1063                 return IM_STATUS_NOT_SUPPORTED;
1064             }
1065             break;
1066         case IM_ALPHA_BLEND_DST_OVER :
1067             if (pat_enable) {
1068                 if (!NormalRgaFormatHasAlpha(pat_fmt)) {
1069                     IM_LOGW("Blend mode 'dst_over' unsupported pat format without alpha, "
1070                             "format[src,src1,dst] = [0x%x(%s), 0x%x(%s), 0x%x(%s)]",
1071                             src_fmt, translate_format_str(src_fmt),
1072                             pat_fmt, translate_format_str(pat_fmt),
1073                             dst_fmt, translate_format_str(dst_fmt));
1074                     return IM_STATUS_NOT_SUPPORTED;
1075                 }
1076             } else {
1077                 if (!NormalRgaFormatHasAlpha(dst_fmt)) {
1078                     IM_LOGW("Blend mode 'dst_over' unsupported dst format without alpha, "
1079                             "format[src,src1,dst] = [0x%x(%s), 0x%x(%s), 0x%x(%s)]",
1080                             src_fmt, translate_format_str(src_fmt),
1081                             pat_fmt, translate_format_str(pat_fmt),
1082                             dst_fmt, translate_format_str(dst_fmt));
1083                     return IM_STATUS_NOT_SUPPORTED;
1084                 }
1085             }
1086             break;
1087         default :
1088             if (!(NormalRgaFormatHasAlpha(src_fmt) || NormalRgaFormatHasAlpha(dst_fmt))) {
1089                 IM_LOGW("Blend mode unsupported format without alpha, "
1090                         "format[src,src1,dst] = [0x%x(%s), 0x%x(%s), 0x%x(%s)]",
1091                         src_fmt, translate_format_str(src_fmt),
1092                         pat_fmt, translate_format_str(pat_fmt),
1093                         dst_fmt, translate_format_str(dst_fmt));
1094                 return IM_STATUS_NOT_SUPPORTED;
1095             }
1096             break;
1097     }
1098 
1099     /* src1 don't support scale, and src1's size must aqual to dst.' */
1100     if (pat_enable && (pat.width != dst.width || pat.height != dst.height)) {
1101         IM_LOGW("In the three-channel mode Alapha blend, the width and height of the src1 channel "
1102                 "must be equal to the dst channel, src1[w,h] = [%d, %d], dst[w,h] = [%d, %d]",
1103                 pat.width, pat.height, dst.width, dst.height);
1104         return IM_STATUS_NOT_SUPPORTED;
1105     }
1106 
1107     return IM_STATUS_NOERROR;
1108 }
1109 
rga_check_rotate(int mode_usage,rga_info_table_entry & table)1110 IM_STATUS rga_check_rotate(int mode_usage, rga_info_table_entry &table) {
1111     if (table.version & (IM_RGA_HW_VERSION_RGA_1 | IM_RGA_HW_VERSION_RGA_1_PLUS)) {
1112         if (mode_usage & IM_HAL_TRANSFORM_FLIP_H_V) {
1113             IM_LOGW("RGA1/RGA1_PLUS cannot support H_V mirror.");
1114             return IM_STATUS_NOT_SUPPORTED;
1115         }
1116 
1117         if ((mode_usage & (IM_HAL_TRANSFORM_ROT_90 + IM_HAL_TRANSFORM_ROT_180 + IM_HAL_TRANSFORM_ROT_270)) &&
1118             (mode_usage & (IM_HAL_TRANSFORM_FLIP_H + IM_HAL_TRANSFORM_FLIP_V + IM_HAL_TRANSFORM_FLIP_H_V))) {
1119             IM_LOGW("RGA1/RGA1_PLUS cannot support rotate with mirror.");
1120             return IM_STATUS_NOT_SUPPORTED;
1121         }
1122     }
1123 
1124     return IM_STATUS_NOERROR;
1125 }
1126 
rga_check_feature(rga_buffer_t src,rga_buffer_t pat,rga_buffer_t dst,int pat_enable,int mode_usage,int feature_usage)1127 IM_STATUS rga_check_feature(rga_buffer_t src, rga_buffer_t pat, rga_buffer_t dst,
1128                                    int pat_enable, int mode_usage, int feature_usage) {
1129     if ((mode_usage & IM_COLOR_FILL) && (~feature_usage & IM_RGA_SUPPORT_FEATURE_COLOR_FILL)) {
1130         IM_LOGW("The platform does not support color fill featrue. \n%s",
1131                 querystring(RGA_FEATURE));
1132         return IM_STATUS_NOT_SUPPORTED;
1133     }
1134 
1135     if ((mode_usage & IM_COLOR_PALETTE) && (~feature_usage & IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE)) {
1136         IM_LOGW("The platform does not support color palette featrue. \n%s",
1137                 querystring(RGA_FEATURE));
1138         return IM_STATUS_NOT_SUPPORTED;
1139     }
1140 
1141     if ((mode_usage & IM_ROP) && (~feature_usage & IM_RGA_SUPPORT_FEATURE_ROP)) {
1142         IM_LOGW("The platform does not support ROP featrue. \n%s",
1143                 querystring(RGA_FEATURE));
1144         return IM_STATUS_NOT_SUPPORTED;
1145     }
1146 
1147     if ((mode_usage & IM_NN_QUANTIZE) && (~feature_usage & IM_RGA_SUPPORT_FEATURE_QUANTIZE)) {
1148         IM_LOGW("The platform does not support quantize featrue. \n%s",
1149                 querystring(RGA_FEATURE));
1150         return IM_STATUS_NOT_SUPPORTED;
1151     }
1152 
1153     if ((pat_enable ? (pat.color_space_mode & IM_RGB_TO_YUV_MASK) : 0) && (~feature_usage & IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC)) {
1154         IM_LOGW("The platform does not support src1 channel RGB2YUV color space convert featrue. \n%s",
1155                 querystring(RGA_FEATURE));
1156         return IM_STATUS_NOT_SUPPORTED;
1157     }
1158 
1159     if ((src.color_space_mode & IM_FULL_CSC_MASK ||
1160         dst.color_space_mode & IM_FULL_CSC_MASK ||
1161         (pat_enable ? (pat.color_space_mode & IM_FULL_CSC_MASK) : 0)) &&
1162         (~feature_usage & IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC)) {
1163         IM_LOGW("The platform does not support dst channel full color space convert(Y2Y/Y2R) featrue. \n%s",
1164                 querystring(RGA_FEATURE));
1165         return IM_STATUS_NOT_SUPPORTED;
1166     }
1167 
1168     if ((mode_usage & IM_MOSAIC) && (~feature_usage & IM_RGA_SUPPORT_FEATURE_MOSAIC)) {
1169         IM_LOGW("The platform does not support mosaic featrue. \n%s",
1170                 querystring(RGA_FEATURE));
1171         return IM_STATUS_NOT_SUPPORTED;
1172     }
1173 
1174     if ((mode_usage & IM_OSD) && (~feature_usage & IM_RGA_SUPPORT_FEATURE_OSD)) {
1175         IM_LOGW("The platform does not support osd featrue. \n%s",
1176                 querystring(RGA_FEATURE));
1177         return IM_STATUS_NOT_SUPPORTED;
1178     }
1179 
1180     if ((mode_usage & IM_PRE_INTR) && (~feature_usage & IM_RGA_SUPPORT_FEATURE_PRE_INTR)) {
1181         IM_LOGW("The platform does not support pre_intr featrue. \n%s",
1182                 querystring(RGA_FEATURE));
1183         return IM_STATUS_NOT_SUPPORTED;
1184     }
1185 
1186     return IM_STATUS_NOERROR;
1187 }
1188 
rga_check(const rga_buffer_t src,const rga_buffer_t dst,const rga_buffer_t pat,const im_rect src_rect,const im_rect dst_rect,const im_rect pat_rect,int mode_usage)1189 IM_STATUS rga_check(const rga_buffer_t src, const rga_buffer_t dst, const rga_buffer_t pat,
1190                     const im_rect src_rect, const im_rect dst_rect, const im_rect pat_rect, int mode_usage) {
1191     bool pat_enable = 0;
1192     IM_STATUS ret = IM_STATUS_NOERROR;
1193     rga_info_table_entry rga_info;
1194 
1195     memset(&rga_info, 0x0, sizeof(rga_info));
1196     ret = rga_get_info(&rga_info);
1197     if (IM_STATUS_FAILED == ret) {
1198         IM_LOGE("rga im2d: rga2 get info failed!\n");
1199         return IM_STATUS_FAILED;
1200     }
1201 
1202     if (mode_usage & IM_ALPHA_BLEND_MASK) {
1203         if (rga_is_buffer_valid(pat))
1204             pat_enable = 1;
1205     }
1206 
1207     /**************** feature judgment ****************/
1208     ret = rga_check_feature(src, pat, dst, pat_enable, mode_usage, rga_info.feature);
1209     if (ret != IM_STATUS_NOERROR)
1210         return ret;
1211 
1212     /**************** info judgment ****************/
1213     if (~mode_usage & IM_COLOR_FILL) {
1214         ret = rga_check_info("src", src, src_rect, rga_info.input_resolution);
1215         if (ret != IM_STATUS_NOERROR)
1216             return ret;
1217         ret = rga_check_format("src", src, src_rect, rga_info.input_format, mode_usage);
1218         if (ret != IM_STATUS_NOERROR)
1219             return ret;
1220         ret = rga_check_align("src", src, rga_info.byte_stride, true);
1221         if (ret != IM_STATUS_NOERROR)
1222             return ret;
1223     }
1224     if (pat_enable) {
1225         /* RGA1 cannot support src1. */
1226         if (rga_info.version & (IM_RGA_HW_VERSION_RGA_1 | IM_RGA_HW_VERSION_RGA_1_PLUS)) {
1227             IM_LOGW("RGA1/RGA1_PLUS cannot support src1.");
1228             return IM_STATUS_NOT_SUPPORTED;
1229         }
1230 
1231 
1232         ret = rga_check_info("pat", pat, pat_rect, rga_info.input_resolution);
1233         if (ret != IM_STATUS_NOERROR)
1234             return ret;
1235         ret = rga_check_format("pat", pat, pat_rect, rga_info.input_format, mode_usage);
1236         if (ret != IM_STATUS_NOERROR)
1237             return ret;
1238         ret = rga_check_align("pat", pat, rga_info.byte_stride, true);
1239         if (ret != IM_STATUS_NOERROR)
1240             return ret;
1241     }
1242     ret = rga_check_info("dst", dst, dst_rect, rga_info.output_resolution);
1243     if (ret != IM_STATUS_NOERROR)
1244         return ret;
1245     ret = rga_check_format("dst", dst, dst_rect, rga_info.output_format, mode_usage);
1246     if (ret != IM_STATUS_NOERROR)
1247         return ret;
1248     ret = rga_check_align("dst", dst, rga_info.byte_stride, false);
1249     if (ret != IM_STATUS_NOERROR)
1250         return ret;
1251 
1252     if ((~mode_usage & IM_COLOR_FILL)) {
1253         ret = rga_check_limit(src, dst, rga_info.scale_limit, mode_usage);
1254         if (ret != IM_STATUS_NOERROR)
1255             return ret;
1256     }
1257 
1258     if (mode_usage & IM_ALPHA_BLEND_MASK) {
1259         ret = rga_check_blend(src, pat, dst, pat_enable, mode_usage);
1260         if (ret != IM_STATUS_NOERROR)
1261             return ret;
1262     }
1263 
1264     ret = rga_check_rotate(mode_usage, rga_info);
1265     if (ret != IM_STATUS_NOERROR)
1266         return ret;
1267 
1268     return IM_STATUS_NOERROR;
1269 }
1270 
rga_check_external(rga_buffer_t src,rga_buffer_t dst,rga_buffer_t pat,im_rect src_rect,im_rect dst_rect,im_rect pat_rect,int mode_usage)1271 IM_STATUS rga_check_external(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat,
1272                              im_rect src_rect, im_rect dst_rect, im_rect pat_rect,
1273                              int mode_usage) {
1274     int ret;
1275     int format;
1276 
1277     if (mode_usage & IM_CROP) {
1278         dst_rect.width = src_rect.width;
1279         dst_rect.height = src_rect.height;
1280     }
1281 
1282     rga_apply_rect(&src, &src_rect);
1283     format = convert_to_rga_format(src.format);
1284     if (format == RK_FORMAT_UNKNOWN) {
1285         IM_LOGW("Invaild src format [0x%x]!\n", src.format);
1286         return IM_STATUS_NOT_SUPPORTED;
1287     }
1288     src.format = format;
1289 
1290     rga_apply_rect(&dst, &dst_rect);
1291     format = convert_to_rga_format(dst.format);
1292     if (format == RK_FORMAT_UNKNOWN) {
1293         IM_LOGW("Invaild dst format [0x%x]!\n", dst.format);
1294         return IM_STATUS_NOT_SUPPORTED;
1295     }
1296     dst.format = format;
1297 
1298     if (rga_is_buffer_valid(pat)) {
1299         rga_apply_rect(&pat, &pat_rect);
1300         format = convert_to_rga_format(pat.format);
1301         if (format == RK_FORMAT_UNKNOWN) {
1302             IM_LOGW("Invaild pat format [0x%x]!\n", pat.format);
1303             return IM_STATUS_NOT_SUPPORTED;
1304         }
1305         pat.format = format;
1306     }
1307 
1308     return rga_check(src, dst, pat, src_rect, dst_rect, pat_rect, mode_usage);
1309 }
1310 
rga_import_buffers(struct rga_buffer_pool * buffer_pool)1311 IM_API IM_STATUS rga_import_buffers(struct rga_buffer_pool *buffer_pool) {
1312     int ret = 0;
1313 
1314     ret = rga_get_context();
1315     if (ret != IM_STATUS_SUCCESS)
1316         return (IM_STATUS)ret;
1317 
1318     if (buffer_pool == NULL) {
1319         IM_LOGW("buffer pool is null!");
1320         return IM_STATUS_FAILED;
1321     }
1322 
1323     ret = ioctl(rgaCtx->rgaFd, RGA_IOC_IMPORT_BUFFER, buffer_pool);
1324     if (ret < 0) {
1325         IM_LOGW("RGA_IOC_IMPORT_BUFFER fail! %s", strerror(errno));
1326         return IM_STATUS_FAILED;
1327     }
1328 
1329     return IM_STATUS_SUCCESS;
1330 }
1331 
rga_import_buffer(uint64_t memory,int type,uint32_t size)1332 IM_API rga_buffer_handle_t rga_import_buffer(uint64_t memory, int type, uint32_t size) {
1333     struct rga_buffer_pool buffer_pool;
1334     struct rga_external_buffer buffers[1];
1335 
1336     memset(&buffer_pool, 0x0, sizeof(buffer_pool));
1337     memset(buffers, 0x0, sizeof(buffers));
1338 
1339     buffers[0].type = type;
1340     buffers[0].memory = memory;
1341     buffers[0].memory_info.size = size;
1342 
1343     buffer_pool.buffers = ptr_to_u64(buffers);
1344     buffer_pool.size = 1;
1345 
1346     if (rga_import_buffers(&buffer_pool) != IM_STATUS_SUCCESS)
1347         return -1;
1348 
1349     return buffers[0].handle;
1350 }
1351 
rga_import_buffer(uint64_t memory,int type,im_handle_param_t * param)1352 IM_API rga_buffer_handle_t rga_import_buffer(uint64_t memory, int type, im_handle_param_t *param) {
1353     int format;
1354     struct rga_buffer_pool buffer_pool;
1355     struct rga_external_buffer buffers[1];
1356 
1357     memset(&buffer_pool, 0x0, sizeof(buffer_pool));
1358     memset(buffers, 0x0, sizeof(buffers));
1359 
1360     buffers[0].type = type;
1361     buffers[0].memory = memory;
1362     memcpy(&buffers[0].memory_info, param, sizeof(*param));
1363     format = convert_to_rga_format(buffers[0].memory_info.format);
1364     if (format == RK_FORMAT_UNKNOWN) {
1365         IM_LOGW("Invaild format [0x%x]!\n", buffers[0].memory_info.format);
1366         return IM_STATUS_NOT_SUPPORTED;
1367     }
1368     buffers[0].memory_info.format = format >> 8;
1369 
1370     buffer_pool.buffers = ptr_to_u64(buffers);
1371     buffer_pool.size = 1;
1372 
1373     if (rga_import_buffers(&buffer_pool) != IM_STATUS_SUCCESS)
1374         return 0;
1375 
1376     return buffers[0].handle;
1377 }
1378 
rga_release_buffers(struct rga_buffer_pool * buffer_pool)1379 IM_API IM_STATUS rga_release_buffers(struct rga_buffer_pool *buffer_pool) {
1380     int ret = 0;
1381 
1382     ret = rga_get_context();
1383     if (ret != IM_STATUS_SUCCESS)
1384         return (IM_STATUS)ret;
1385 
1386     if (buffer_pool == NULL) {
1387         IM_LOGW("buffer pool is null!");
1388         return IM_STATUS_FAILED;
1389     }
1390 
1391     ret = ioctl(rgaCtx->rgaFd, RGA_IOC_RELEASE_BUFFER, buffer_pool);
1392     if (ret < 0) {
1393         IM_LOGW("RGA_IOC_RELEASE_BUFFER fail! %s", strerror(errno));
1394         return IM_STATUS_FAILED;
1395     }
1396 
1397     return IM_STATUS_SUCCESS;
1398 }
1399 
rga_release_buffer(int handle)1400 IM_API IM_STATUS rga_release_buffer(int handle) {
1401     struct rga_buffer_pool buffer_pool;
1402     struct rga_external_buffer buffers[1];
1403 
1404     memset(&buffer_pool, 0x0, sizeof(buffer_pool));
1405     memset(buffers, 0x0, sizeof(buffers));
1406 
1407     buffers[0].handle = handle;
1408 
1409     buffer_pool.buffers = ptr_to_u64(buffers);
1410     buffer_pool.size = 1;
1411 
1412     return rga_release_buffers(&buffer_pool);
1413 }
1414 
rga_dump_channel_info(int log_level,const char * name,im_rect & rect,rga_buffer_t & image)1415 static void rga_dump_channel_info(int log_level, const char *name, im_rect &rect, rga_buffer_t &image) {
1416     log_level |= IM_LOG_FORCE;
1417 
1418     IM_LOG(log_level,
1419            "%s_channel: \n"
1420            "  rect[x,y,w,h] = [%d, %d, %d, %d]\n"
1421            "  image[w,h,ws,hs,f] = [%d, %d, %d, %d, %s]\n"
1422            "  buffer[handle,fd,va,pa] = [%d, %d, %lx, %lx]\n"
1423            "  color_space = 0x%x, global_alpha = 0x%x, rd_mode = 0x%x\n",
1424            name,
1425            rect.x, rect.y, rect.width, rect.height,
1426            image.width, image.height, image.wstride, image.hstride, translate_format_str(image.format),
1427            image.handle, image.fd, (unsigned long)image.vir_addr, (unsigned long)image.phy_addr,
1428            image.color_space_mode, image.global_alpha, image.rd_mode);
1429 }
1430 
rga_dump_osd_info(int log_level,im_osd_t & osd_info)1431 static void rga_dump_osd_info(int log_level, im_osd_t &osd_info) {
1432     IM_LOG(log_level, "osd_mode[0x%x]:\n", osd_info.osd_mode);
1433 
1434     IM_LOG(log_level, "  block: \n"
1435                       "    width_mode[0x%x], width/witdh_index[0x%x], block_count[%d]\n"
1436                       "    background_config[0x%x], direction[0x%x], color_mode[0x%x]\n"
1437                       "    normal_color[0x%x], invert_color[0x%x]\n",
1438            osd_info.block_parm.width_mode, osd_info.block_parm.width, osd_info.block_parm.block_count,
1439            osd_info.block_parm.background_config, osd_info.block_parm.direction, osd_info.block_parm.color_mode,
1440            osd_info.block_parm.normal_color.value, osd_info.block_parm.invert_color.value);
1441 
1442     IM_LOG(log_level, "  invert_config:\n"
1443                       "    channel[0x%x], flags_mode[0x%x], flages_index[%d] threash[0x%x]\n"
1444                       "    flages: invert[0x%llx], current[0x%llx]\n"
1445                       "    invert_mode[%x]",
1446            osd_info.invert_config.invert_channel, osd_info.invert_config.flags_mode,
1447            osd_info.invert_config.flags_index, osd_info.invert_config.threash,
1448            (unsigned long long)osd_info.invert_config.invert_flags,
1449            (unsigned long long)osd_info.invert_config.current_flags,
1450            osd_info.invert_config.invert_mode);
1451     if (osd_info.invert_config.invert_mode == IM_OSD_INVERT_USE_FACTOR)
1452         IM_LOG(log_level, "    factor[min,max] = alpha[0x%x, 0x%x], yg[0x%x, 0x%x], crb[0x%x, 0x%x]\n",
1453                osd_info.invert_config.factor.alpha_min, osd_info.invert_config.factor.alpha_max,
1454                osd_info.invert_config.factor.yg_min, osd_info.invert_config.factor.yg_max,
1455                osd_info.invert_config.factor.crb_min, osd_info.invert_config.factor.crb_max);
1456     else
1457         IM_LOG(log_level, "\n");
1458 
1459     IM_LOG(log_level, "  bpp2rgb info:\n"
1460                       "    ac_swap[0x%x], endian_swap[0x%x], color0[0x%x], color1[0x%x]\n",
1461            osd_info.bpp2_info.ac_swap, osd_info.bpp2_info.endian_swap,
1462            osd_info.bpp2_info.color0.value, osd_info.bpp2_info.color1.value);
1463 }
1464 
rga_dump_opt(int log_level,im_opt_t & opt,int usage)1465 static void rga_dump_opt(int log_level, im_opt_t &opt, int usage) {
1466     log_level |= IM_LOG_FORCE;
1467 
1468     IM_LOG(log_level, "opt version[0x%x]:\n", opt.version);
1469     IM_LOG(log_level, "set_core[0x%x], priority[%d]\n", opt.core, opt.priority);
1470 
1471     if (usage & IM_COLOR_FILL)
1472         IM_LOG(log_level, "color[0x%x] ", opt.color);
1473     if (usage & IM_MOSAIC)
1474         IM_LOG(log_level, "mosaic[%d] ", opt.mosaic_mode);
1475     if (usage & IM_ROP)
1476         IM_LOG(log_level, "rop[0x%x] ", opt.rop_code);
1477     if (usage & IM_ALPHA_COLORKEY_MASK)
1478         IM_LOG(log_level, "color_key[min,max] = [0x%x, 0x%x] ",
1479                opt.colorkey_range.min, opt.colorkey_range.max);
1480     if (usage & (IM_COLOR_FILL | IM_MOSAIC | IM_ROP | IM_ALPHA_COLORKEY_MASK))
1481         IM_LOG(log_level, "\n");
1482 
1483     if (usage & IM_NN_QUANTIZE)
1484         IM_LOG(log_level, "nn:\n"
1485                           "  scale[r,g,b] = [%d, %d, %d], offset[r,g,b] = [0x%x, 0x%x, 0x%x]\n",
1486                opt.nn.scale_r, opt.nn.scale_g, opt.nn.scale_b,
1487                opt.nn.offset_r, opt.nn.offset_g, opt.nn.offset_b);
1488 
1489     if (usage & IM_OSD)
1490         rga_dump_osd_info(log_level, opt.osd_config);
1491 
1492     if (usage & IM_PRE_INTR)
1493         IM_LOG(log_level, "pre_intr:\n"
1494                           "  flags[0x%x], read_threshold[0x%x], write_start[0x%x], write_step[0x%x]\n",
1495                opt.intr_config.flags, opt.intr_config.read_threshold,
1496                opt.intr_config.write_start, opt.intr_config.write_step);
1497 }
1498 
rga_get_opt(im_opt_t * opt,void * ptr)1499 IM_STATUS rga_get_opt(im_opt_t *opt, void *ptr) {
1500     if (opt == NULL || ptr == NULL)
1501         return IM_STATUS_FAILED;
1502 
1503     /*
1504      * Prevent the value of 'color' from being mistakenly used as
1505      * version information.
1506      */
1507     if (rga_version_compare(RGA_GET_API_VERSION(*(im_api_version_t *)ptr),
1508                             (struct rga_version_t){ 2, 0, 0, {0}}) > 0)
1509         return IM_STATUS_FAILED;
1510 
1511     if (rga_version_compare(RGA_GET_API_VERSION(*(im_api_version_t *)ptr),
1512                             (struct rga_version_t){ 1, 7, 2, {0}}) <= 0) {
1513         opt->color = ((im_opt_t *)ptr)->color;
1514         memcpy(&opt->colorkey_range, &((im_opt_t *)ptr)->colorkey_range, sizeof(im_colorkey_range));
1515         memcpy(&opt->nn, &((im_opt_t *)ptr)->nn, sizeof(im_nn_t));
1516         opt->rop_code = ((im_opt_t *)ptr)->rop_code;
1517         opt->priority = ((im_opt_t *)ptr)->priority;
1518         opt->core = ((im_opt_t *)ptr)->core;
1519     } else {
1520         memcpy(opt, ptr, sizeof(im_opt_t));
1521     }
1522 
1523     return IM_STATUS_SUCCESS;
1524 }
1525 
rga_task_submit(im_job_handle_t job_handle,rga_buffer_t src,rga_buffer_t dst,rga_buffer_t pat,im_rect srect,im_rect drect,im_rect prect,int acquire_fence_fd,int * release_fence_fd,im_opt_t * opt_ptr,int usage)1526 static IM_STATUS rga_task_submit(im_job_handle_t job_handle, rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat,
1527                                  im_rect srect, im_rect drect, im_rect prect,
1528                                  int acquire_fence_fd, int *release_fence_fd,
1529                                  im_opt_t *opt_ptr, int usage) {
1530     int ret;
1531     int format;
1532     rga_info_t srcinfo;
1533     rga_info_t dstinfo;
1534     rga_info_t patinfo;
1535 
1536     im_opt_t opt;
1537 
1538     if (rga_get_opt(&opt, opt_ptr) == IM_STATUS_FAILED)
1539         memset(&opt, 0x0, sizeof(opt));
1540 
1541     memset(&srcinfo, 0, sizeof(rga_info_t));
1542     memset(&dstinfo, 0, sizeof(rga_info_t));
1543     memset(&patinfo, 0, sizeof(rga_info_t));
1544 
1545     if (usage & IM_COLOR_FILL)
1546         ret = rga_set_buffer_info(dst, &dstinfo);
1547     else
1548         ret = rga_set_buffer_info(src, dst, &srcinfo, &dstinfo);
1549 
1550     if (ret <= 0)
1551         return (IM_STATUS)ret;
1552 
1553     rga_apply_rect(&src, &srect);
1554     format = convert_to_rga_format(src.format);
1555     if (format == RK_FORMAT_UNKNOWN) {
1556         IM_LOGW("Invaild src format [0x%x]!\n", src.format);
1557         return IM_STATUS_NOT_SUPPORTED;
1558     }
1559     src.format = format;
1560 
1561     rga_set_rect(&srcinfo.rect, srect.x, srect.y, src.width, src.height, src.wstride, src.hstride, src.format);
1562 
1563     rga_apply_rect(&dst, &drect);
1564     format = convert_to_rga_format(dst.format);
1565     if (format == RK_FORMAT_UNKNOWN) {
1566         IM_LOGW("Invaild dst format [0x%x]!\n", dst.format);
1567         return IM_STATUS_NOT_SUPPORTED;
1568     }
1569     dst.format = format;
1570 
1571     rga_set_rect(&dstinfo.rect, drect.x, drect.y, dst.width, dst.height, dst.wstride, dst.hstride, dst.format);
1572 
1573     if (((usage & IM_COLOR_PALETTE) || (usage & IM_ALPHA_BLEND_MASK)) &&
1574         rga_is_buffer_valid(pat)) {
1575 
1576         ret = rga_set_buffer_info(pat, &patinfo);
1577         if (ret <= 0)
1578             return (IM_STATUS)ret;
1579 
1580         rga_apply_rect(&pat, &prect);
1581         format = convert_to_rga_format(pat.format);
1582         if (format == RK_FORMAT_UNKNOWN) {
1583             IM_LOGW("Invaild pat format [0x%x]!\n", pat.format);
1584             return IM_STATUS_NOT_SUPPORTED;
1585         }
1586         pat.format = format;
1587 
1588         rga_set_rect(&patinfo.rect, prect.x, prect.y, pat.width, pat.height, pat.wstride, pat.hstride, pat.format);
1589     }
1590 
1591     ret = rga_check(src, dst, pat, srect, drect, prect, usage);
1592     if(ret != IM_STATUS_NOERROR)
1593         return (IM_STATUS)ret;
1594 
1595     /* Transform */
1596     if (usage & IM_HAL_TRANSFORM_MASK) {
1597         switch (usage & (IM_HAL_TRANSFORM_ROT_90 + IM_HAL_TRANSFORM_ROT_180 + IM_HAL_TRANSFORM_ROT_270)) {
1598             case IM_HAL_TRANSFORM_ROT_90:
1599                 srcinfo.rotation = HAL_TRANSFORM_ROT_90;
1600                 break;
1601             case IM_HAL_TRANSFORM_ROT_180:
1602                 srcinfo.rotation = HAL_TRANSFORM_ROT_180;
1603                 break;
1604             case IM_HAL_TRANSFORM_ROT_270:
1605                 srcinfo.rotation = HAL_TRANSFORM_ROT_270;
1606                 break;
1607         }
1608 
1609         switch (usage & (IM_HAL_TRANSFORM_FLIP_V + IM_HAL_TRANSFORM_FLIP_H + IM_HAL_TRANSFORM_FLIP_H_V)) {
1610             case IM_HAL_TRANSFORM_FLIP_V:
1611                 srcinfo.rotation |= srcinfo.rotation ?
1612                                     HAL_TRANSFORM_FLIP_V << 4 :
1613                                     HAL_TRANSFORM_FLIP_V;
1614                 break;
1615             case IM_HAL_TRANSFORM_FLIP_H:
1616                 srcinfo.rotation |= srcinfo.rotation ?
1617                                     HAL_TRANSFORM_FLIP_H << 4 :
1618                                     HAL_TRANSFORM_FLIP_H;
1619                 break;
1620             case IM_HAL_TRANSFORM_FLIP_H_V:
1621                 srcinfo.rotation |= srcinfo.rotation ?
1622                                     HAL_TRANSFORM_FLIP_H_V << 4 :
1623                                     HAL_TRANSFORM_FLIP_H_V;
1624                 break;
1625         }
1626 
1627         if(srcinfo.rotation ==0)
1628             IM_LOGE("rga_im2d: Could not find rotate/flip usage : 0x%x \n", usage);
1629     }
1630 
1631     /* Blend */
1632     if (usage & IM_ALPHA_BLEND_MASK) {
1633         switch(usage & IM_ALPHA_BLEND_MASK) {
1634             case IM_ALPHA_BLEND_SRC:
1635                 srcinfo.blend = 0x1;
1636                 break;
1637             case IM_ALPHA_BLEND_DST:
1638                 srcinfo.blend = 0x2;
1639                 break;
1640             case IM_ALPHA_BLEND_SRC_OVER:
1641                 srcinfo.blend = (usage & IM_ALPHA_BLEND_PRE_MUL) ? 0x405 : 0x105;
1642                 break;
1643             case IM_ALPHA_BLEND_SRC_IN:
1644                 break;
1645             case IM_ALPHA_BLEND_DST_IN:
1646                 break;
1647             case IM_ALPHA_BLEND_SRC_OUT:
1648                 break;
1649             case IM_ALPHA_BLEND_DST_OVER:
1650                 srcinfo.blend = (usage & IM_ALPHA_BLEND_PRE_MUL) ? 0x504 : 0x501;
1651                 break;
1652             case IM_ALPHA_BLEND_SRC_ATOP:
1653                 break;
1654             case IM_ALPHA_BLEND_DST_OUT:
1655                 break;
1656             case IM_ALPHA_BLEND_XOR:
1657                 break;
1658         }
1659 
1660         if(srcinfo.blend == 0)
1661             IM_LOGE("rga_im2d: Could not find blend usage : 0x%x \n", usage);
1662 
1663         /* set global alpha */
1664         if (src.global_alpha > 0)
1665             srcinfo.blend ^= src.global_alpha << 16;
1666         else {
1667             srcinfo.blend ^= 0xFF << 16;
1668         }
1669     }
1670 
1671     /* color key */
1672     if (usage & IM_ALPHA_COLORKEY_MASK) {
1673         srcinfo.blend = 0xff0105;
1674 
1675         srcinfo.colorkey_en = 1;
1676         srcinfo.colorkey_min = opt.colorkey_range.min;
1677         srcinfo.colorkey_max = opt.colorkey_range.max;
1678         switch (usage & IM_ALPHA_COLORKEY_MASK) {
1679             case IM_ALPHA_COLORKEY_NORMAL:
1680                 srcinfo.colorkey_mode = 0;
1681                 break;
1682             case IM_ALPHA_COLORKEY_INVERTED:
1683                 srcinfo.colorkey_mode = 1;
1684                 break;
1685         }
1686     }
1687 
1688     /* OSD */
1689     if (usage & IM_OSD) {
1690         srcinfo.osd_info.enable = true;
1691 
1692         srcinfo.osd_info.mode_ctrl.mode = opt.osd_config.osd_mode;
1693 
1694         srcinfo.osd_info.mode_ctrl.width_mode = opt.osd_config.block_parm.width_mode;
1695         if (opt.osd_config.block_parm.width_mode == IM_OSD_BLOCK_MODE_NORMAL)
1696             srcinfo.osd_info.mode_ctrl.block_fix_width = opt.osd_config.block_parm.width;
1697         else if (opt.osd_config.block_parm.width_mode == IM_OSD_BLOCK_MODE_DIFFERENT)
1698             srcinfo.osd_info.mode_ctrl.unfix_index = opt.osd_config.block_parm.width_index;
1699         srcinfo.osd_info.mode_ctrl.block_num = opt.osd_config.block_parm.block_count;
1700         srcinfo.osd_info.mode_ctrl.default_color_sel = opt.osd_config.block_parm.background_config;
1701         srcinfo.osd_info.mode_ctrl.direction_mode = opt.osd_config.block_parm.direction;
1702         srcinfo.osd_info.mode_ctrl.color_mode = opt.osd_config.block_parm.color_mode;
1703 
1704         if (pat.format == RK_FORMAT_RGBA2BPP) {
1705             srcinfo.osd_info.bpp2_info.ac_swap = opt.osd_config.bpp2_info.ac_swap;
1706             srcinfo.osd_info.bpp2_info.endian_swap = opt.osd_config.bpp2_info.endian_swap;
1707             srcinfo.osd_info.bpp2_info.color0.value = opt.osd_config.bpp2_info.color0.value;
1708             srcinfo.osd_info.bpp2_info.color1.value = opt.osd_config.bpp2_info.color1.value;
1709         } else {
1710             srcinfo.osd_info.bpp2_info.color0.value = opt.osd_config.block_parm.normal_color.value;
1711             srcinfo.osd_info.bpp2_info.color1.value = opt.osd_config.block_parm.invert_color.value;
1712         }
1713 
1714         switch (opt.osd_config.invert_config.invert_channel) {
1715             case IM_OSD_INVERT_CHANNEL_NONE:
1716                 srcinfo.osd_info.mode_ctrl.invert_enable = (0x1 << 1) | (0x1 << 2);
1717                 break;
1718             case IM_OSD_INVERT_CHANNEL_Y_G:
1719                 srcinfo.osd_info.mode_ctrl.invert_enable = 0x1 << 2;
1720                 break;
1721             case IM_OSD_INVERT_CHANNEL_C_RB:
1722                 srcinfo.osd_info.mode_ctrl.invert_enable = 0x1 << 1;
1723                 break;
1724             case IM_OSD_INVERT_CHANNEL_ALPHA:
1725                 srcinfo.osd_info.mode_ctrl.invert_enable = (0x1 << 0) | (0x1 << 1) | (0x1 << 2);
1726                 break;
1727             case IM_OSD_INVERT_CHANNEL_COLOR:
1728                 srcinfo.osd_info.mode_ctrl.invert_enable = 0;
1729                 break;
1730             case IM_OSD_INVERT_CHANNEL_BOTH:
1731                 srcinfo.osd_info.mode_ctrl.invert_enable = 0x1 << 0;
1732         }
1733         srcinfo.osd_info.mode_ctrl.invert_flags_mode = opt.osd_config.invert_config.flags_mode;
1734         srcinfo.osd_info.mode_ctrl.flags_index = opt.osd_config.invert_config.flags_index;
1735 
1736         srcinfo.osd_info.last_flags = opt.osd_config.invert_config.invert_flags;
1737         srcinfo.osd_info.cur_flags = opt.osd_config.invert_config.current_flags;
1738 
1739         srcinfo.osd_info.mode_ctrl.invert_mode = opt.osd_config.invert_config.invert_mode;
1740         if (opt.osd_config.invert_config.invert_mode == IM_OSD_INVERT_USE_FACTOR) {
1741             srcinfo.osd_info.cal_factor.alpha_max = opt.osd_config.invert_config.factor.alpha_max;
1742             srcinfo.osd_info.cal_factor.alpha_min = opt.osd_config.invert_config.factor.alpha_min;
1743             srcinfo.osd_info.cal_factor.crb_max = opt.osd_config.invert_config.factor.crb_max;
1744             srcinfo.osd_info.cal_factor.crb_min = opt.osd_config.invert_config.factor.crb_min;
1745             srcinfo.osd_info.cal_factor.yg_max = opt.osd_config.invert_config.factor.yg_max;
1746             srcinfo.osd_info.cal_factor.yg_min = opt.osd_config.invert_config.factor.yg_min;
1747         }
1748         srcinfo.osd_info.mode_ctrl.invert_thresh = opt.osd_config.invert_config.threash;
1749     }
1750 
1751     /* set NN quantize */
1752     if (usage & IM_NN_QUANTIZE) {
1753         dstinfo.nn.nn_flag = 1;
1754         dstinfo.nn.scale_r  = opt.nn.scale_r;
1755         dstinfo.nn.scale_g  = opt.nn.scale_g;
1756         dstinfo.nn.scale_b  = opt.nn.scale_b;
1757         dstinfo.nn.offset_r = opt.nn.offset_r;
1758         dstinfo.nn.offset_g = opt.nn.offset_g;
1759         dstinfo.nn.offset_b = opt.nn.offset_b;
1760     }
1761 
1762     /* set ROP */
1763     if (usage & IM_ROP) {
1764         srcinfo.rop_code = opt.rop_code;
1765     }
1766 
1767     /* set mosaic */
1768     if (usage & IM_MOSAIC) {
1769         srcinfo.mosaic_info.enable = true;
1770         srcinfo.mosaic_info.mode = opt.mosaic_mode;
1771     }
1772 
1773     /* set intr config */
1774     if (usage & IM_PRE_INTR) {
1775         srcinfo.pre_intr.enable = true;
1776 
1777         srcinfo.pre_intr.read_intr_en = opt.intr_config.flags & IM_INTR_READ_INTR ? true : false;
1778         if (srcinfo.pre_intr.read_intr_en) {
1779             srcinfo.pre_intr.read_intr_en = true;
1780             srcinfo.pre_intr.read_hold_en = opt.intr_config.flags & IM_INTR_READ_HOLD ? true : false;
1781             srcinfo.pre_intr.read_threshold = opt.intr_config.read_threshold;
1782         }
1783 
1784         srcinfo.pre_intr.write_intr_en = opt.intr_config.flags & IM_INTR_WRITE_INTR ? true : false;
1785         if (srcinfo.pre_intr.write_intr_en > 0) {
1786                 srcinfo.pre_intr.write_start = opt.intr_config.write_start;
1787                 srcinfo.pre_intr.write_step = opt.intr_config.write_step;
1788         }
1789     }
1790 
1791     /* special config for color space convert */
1792     if ((dst.color_space_mode & IM_YUV_TO_RGB_MASK) && (dst.color_space_mode & IM_RGB_TO_YUV_MASK)) {
1793         if (rga_is_buffer_valid(pat) &&
1794             NormalRgaIsYuvFormat(src.format) &&
1795             NormalRgaIsRgbFormat(pat.format) &&
1796             NormalRgaIsYuvFormat(dst.format)) {
1797             dstinfo.color_space_mode = dst.color_space_mode;
1798         } else {
1799             IM_LOGW("Not yuv + rgb -> yuv does not need for color_sapce_mode R2Y & Y2R, please fix, "
1800                     "src_fromat = 0x%x(%s), src1_format = 0x%x(%s), dst_format = 0x%x(%s)",
1801                     src.format, translate_format_str(src.format),
1802                     pat.format, translate_format_str(pat.format),
1803                     dst.format, translate_format_str(dst.format));
1804             return IM_STATUS_ILLEGAL_PARAM;
1805         }
1806     } else if (dst.color_space_mode & (IM_YUV_TO_RGB_MASK)) {
1807         if (rga_is_buffer_valid(pat) &&
1808             NormalRgaIsYuvFormat(src.format) &&
1809             NormalRgaIsRgbFormat(pat.format) &&
1810             NormalRgaIsRgbFormat(dst.format)) {
1811             dstinfo.color_space_mode = dst.color_space_mode;
1812         } else if (NormalRgaIsYuvFormat(src.format) &&
1813                    NormalRgaIsRgbFormat(dst.format)) {
1814             dstinfo.color_space_mode = dst.color_space_mode;
1815         } else {
1816             IM_LOGW("Not yuv to rgb does not need for color_sapce_mode, please fix, "
1817                     "src_fromat = 0x%x(%s), src1_format = 0x%x(%s), dst_format = 0x%x(%s)",
1818                     src.format, translate_format_str(src.format),
1819                     pat.format, rga_is_buffer_valid(pat) ? translate_format_str(pat.format) : "none",
1820                     dst.format, translate_format_str(dst.format));
1821             return IM_STATUS_ILLEGAL_PARAM;
1822         }
1823     } else if (dst.color_space_mode & (IM_RGB_TO_YUV_MASK)) {
1824         if (rga_is_buffer_valid(pat) &&
1825             NormalRgaIsRgbFormat(src.format) &&
1826             NormalRgaIsRgbFormat(pat.format) &&
1827             NormalRgaIsYuvFormat(dst.format)) {
1828             dstinfo.color_space_mode = dst.color_space_mode;
1829         } else if (NormalRgaIsRgbFormat(src.format) &&
1830                    NormalRgaIsYuvFormat(dst.format)) {
1831             dstinfo.color_space_mode = dst.color_space_mode;
1832         } else {
1833             IM_LOGW("Not rgb to yuv does not need for color_sapce_mode, please fix, "
1834                     "src_fromat = 0x%x(%s), src1_format = 0x%x(%s), dst_format = 0x%x(%s)",
1835                     src.format, translate_format_str(src.format),
1836                     pat.format, rga_is_buffer_valid(pat) ? translate_format_str(pat.format) : "none",
1837                     dst.format, translate_format_str(dst.format));
1838             return IM_STATUS_ILLEGAL_PARAM;
1839         }
1840     } else if (src.color_space_mode & IM_FULL_CSC_MASK ||
1841                dst.color_space_mode & IM_FULL_CSC_MASK) {
1842         /* Get default color space */
1843         if (src.color_space_mode == IM_COLOR_SPACE_DEFAULT) {
1844             if  (NormalRgaIsRgbFormat(src.format)) {
1845                 src.color_space_mode = IM_RGB_FULL;
1846             } else if (NormalRgaIsYuvFormat(src.format)) {
1847                 src.color_space_mode = IM_YUV_BT601_LIMIT_RANGE;
1848             }
1849         }
1850 
1851         if (dst.color_space_mode == IM_COLOR_SPACE_DEFAULT) {
1852             if  (NormalRgaIsRgbFormat(dst.format)) {
1853                 src.color_space_mode = IM_RGB_FULL;
1854             } else if (NormalRgaIsYuvFormat(dst.format)) {
1855                 src.color_space_mode = IM_YUV_BT601_LIMIT_RANGE;
1856             }
1857         }
1858 
1859         if (src.color_space_mode == IM_RGB_FULL &&
1860             dst.color_space_mode == IM_YUV_BT709_FULL_RANGE) {
1861             dstinfo.color_space_mode = rgb2yuv_709_full;
1862         } else if (src.color_space_mode == IM_YUV_BT601_FULL_RANGE &&
1863                    dst.color_space_mode == IM_YUV_BT709_LIMIT_RANGE) {
1864             dstinfo.color_space_mode = yuv2yuv_601_full_2_709_limit;
1865         } else if (src.color_space_mode == IM_YUV_BT709_LIMIT_RANGE &&
1866                    dst.color_space_mode == IM_YUV_BT601_LIMIT_RANGE) {
1867             dstinfo.color_space_mode = yuv2yuv_709_limit_2_601_limit;
1868         } else if (src.color_space_mode == IM_YUV_BT709_FULL_RANGE &&
1869                    dst.color_space_mode == IM_YUV_BT601_LIMIT_RANGE) {
1870             dstinfo.color_space_mode = yuv2yuv_709_full_2_601_limit;
1871         } else if (src.color_space_mode == IM_YUV_BT709_FULL_RANGE &&
1872                    dst.color_space_mode == IM_YUV_BT601_FULL_RANGE) {
1873             dstinfo.color_space_mode = yuv2yuv_709_full_2_601_full;
1874         } else {
1875             IM_LOGW("Unsupported full csc mode! src_csm = 0x%x, dst_csm = 0x%x",
1876                     src.color_space_mode, dst.color_space_mode);
1877             return IM_STATUS_NOT_SUPPORTED;
1878         }
1879     }
1880 
1881     if (dst.format == RK_FORMAT_Y4) {
1882         switch (dst.color_space_mode) {
1883             case IM_RGB_TO_Y4 :
1884                 dstinfo.dither.enable = 0;
1885                 dstinfo.dither.mode = 0;
1886                 break;
1887             case IM_RGB_TO_Y4_DITHER :
1888                 dstinfo.dither.enable = 1;
1889                 dstinfo.dither.mode = 0;
1890                 break;
1891             case IM_RGB_TO_Y1_DITHER :
1892                 dstinfo.dither.enable = 1;
1893                 dstinfo.dither.mode = 1;
1894                 break;
1895             default :
1896                 dstinfo.dither.enable = 1;
1897                 dstinfo.dither.mode = 0;
1898                 break;
1899         }
1900         dstinfo.dither.lut0_l = 0x3210;
1901         dstinfo.dither.lut0_h = 0x7654;
1902         dstinfo.dither.lut1_l = 0xba98;
1903         dstinfo.dither.lut1_h = 0xfedc;
1904     }
1905 
1906     srcinfo.rd_mode = src.rd_mode;
1907     dstinfo.rd_mode = dst.rd_mode;
1908     if (rga_is_buffer_valid(pat))
1909         patinfo.rd_mode = pat.rd_mode;
1910 
1911     RockchipRga& rkRga(RockchipRga::get());
1912 
1913     if (usage & IM_ASYNC) {
1914         if (release_fence_fd == NULL) {
1915             IM_LOGW("Async mode release_fence_fd cannot be NULL!");
1916             return IM_STATUS_ILLEGAL_PARAM;
1917         }
1918 
1919         dstinfo.sync_mode = RGA_BLIT_ASYNC;
1920 
1921     } else if (usage & IM_SYNC) {
1922         dstinfo.sync_mode = RGA_BLIT_SYNC;
1923     }
1924 
1925     dstinfo.in_fence_fd = acquire_fence_fd;
1926     dstinfo.core = opt.core ? opt.core : g_im2d_context.core;
1927     dstinfo.priority = opt.priority ? opt.priority : g_im2d_context.priority;
1928 
1929     dstinfo.job_handle = job_handle;
1930 
1931     if (usage & IM_COLOR_FILL) {
1932         dstinfo.color = opt.color;
1933         ret = rkRga.RkRgaCollorFill(&dstinfo);
1934     } else if (usage & IM_COLOR_PALETTE) {
1935         ret = rkRga.RkRgaCollorPalette(&srcinfo, &dstinfo, &patinfo);
1936     } else if ((usage & IM_ALPHA_BLEND_MASK) && rga_is_buffer_valid(pat)) {
1937         ret = rkRga.RkRgaBlit(&srcinfo, &dstinfo, &patinfo);
1938     }else {
1939         ret = rkRga.RkRgaBlit(&srcinfo, &dstinfo, NULL);
1940     }
1941 
1942     if (ret) {
1943         IM_LOGE("Failed to call RockChipRga interface, please use 'dmesg' command to view driver error log.");
1944         rga_dump_channel_info(IM_LOG_ERROR | IM_LOG_FORCE, "src", srect, src);
1945         if (rga_is_buffer_valid(pat))
1946             rga_dump_channel_info(IM_LOG_ERROR | IM_LOG_FORCE, "src1/pat", prect, pat);
1947         rga_dump_channel_info(IM_LOG_ERROR | IM_LOG_FORCE, "dst", drect, dst);
1948 
1949         if (opt_ptr != NULL)
1950             rga_dump_opt(IM_LOG_ERROR | IM_LOG_FORCE, *opt_ptr, usage);
1951 
1952         IM_LOGFE("acquir_fence[%d], release_fence_ptr[0x%lx], usage[0x%x]\n",
1953                  acquire_fence_fd, (unsigned long)release_fence_fd, usage);
1954 
1955         return IM_STATUS_FAILED;
1956     }
1957 
1958     if (usage & IM_ASYNC)
1959         *release_fence_fd = dstinfo.out_fence_fd;
1960 
1961     return IM_STATUS_SUCCESS;
1962 }
1963 
rga_single_task_submit(rga_buffer_t src,rga_buffer_t dst,rga_buffer_t pat,im_rect srect,im_rect drect,im_rect prect,int acquire_fence_fd,int * release_fence_fd,im_opt_t * opt_ptr,int usage)1964 IM_STATUS rga_single_task_submit(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat,
1965                                  im_rect srect, im_rect drect, im_rect prect,
1966                                  int acquire_fence_fd, int *release_fence_fd,
1967                                  im_opt_t *opt_ptr, int usage) {
1968     return rga_task_submit(0, src, dst, pat, srect, drect, prect, acquire_fence_fd, release_fence_fd, opt_ptr, usage);
1969 }
1970 
rga_task_submit(im_job_handle_t job_handle,rga_buffer_t src,rga_buffer_t dst,rga_buffer_t pat,im_rect srect,im_rect drect,im_rect prect,im_opt_t * opt_ptr,int usage)1971 IM_STATUS rga_task_submit(im_job_handle_t job_handle, rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat,
1972                           im_rect srect, im_rect drect, im_rect prect, im_opt_t *opt_ptr, int usage) {
1973     return rga_task_submit(job_handle, src, dst, pat, srect, drect, prect, 0, NULL, opt_ptr, usage);
1974 }
1975 
rga_job_create(uint32_t flags)1976 im_job_handle_t rga_job_create(uint32_t flags) {
1977     int ret;
1978     im_job_handle_t job_handle;
1979     im_rga_job_t *job = NULL;
1980 
1981     if (rga_get_context() != IM_STATUS_SUCCESS)
1982         return IM_STATUS_FAILED;
1983 
1984     if (ioctl(rgaCtx->rgaFd, RGA_IOC_REQUEST_CREATE, &flags) < 0) {
1985         IM_LOGE(" %s(%d) start config fail: %s",__FUNCTION__, __LINE__,strerror(errno));
1986         return IM_STATUS_FAILED;
1987     }
1988 
1989     job_handle = flags;
1990 
1991     g_im2d_job_manager.mutex.lock();
1992 
1993     if (g_im2d_job_manager.job_map.count(job_handle) != 0) {
1994         IM_LOGE("job_map error! handle[%d] already exists[%lu]!\n",
1995                 job_handle, (unsigned long)g_im2d_job_manager.job_map.count(job_handle));
1996         ret = IM_STATUS_FAILED;
1997         goto error_cancel_job;
1998     }
1999 
2000     job = (im_rga_job_t *)malloc(sizeof(*job));
2001     if (job == NULL) {
2002         IM_LOGE("rga job alloc error!\n");
2003         ret = IM_STATUS_FAILED;
2004         goto error_cancel_job;
2005     }
2006 
2007     memset(job, 0x0, sizeof(*job));
2008 
2009     job->id = job_handle;
2010     g_im2d_job_manager.job_map[job_handle] = job;
2011     g_im2d_job_manager.job_count++;
2012 
2013     g_im2d_job_manager.mutex.unlock();
2014 
2015     return job_handle;
2016 
2017 error_cancel_job:
2018     g_im2d_job_manager.mutex.unlock();
2019     rga_job_cancel(job_handle);
2020 
2021     return ret;
2022 }
2023 
rga_job_cancel(im_job_handle_t job_handle)2024 IM_STATUS rga_job_cancel(im_job_handle_t job_handle) {
2025     im_rga_job_t *job = NULL;
2026 
2027     if (rga_get_context() != IM_STATUS_SUCCESS)
2028         return IM_STATUS_FAILED;
2029 
2030     g_im2d_job_manager.mutex.lock();
2031 
2032     if (g_im2d_job_manager.job_map.count(job_handle) > 0) {
2033         job = g_im2d_job_manager.job_map[job_handle];
2034         if (job != NULL)
2035             free(job);
2036 
2037         g_im2d_job_manager.job_map.erase(job_handle);
2038     }
2039 
2040     g_im2d_job_manager.job_count--;
2041 
2042     g_im2d_job_manager.mutex.unlock();
2043 
2044     if (ioctl(rgaCtx->rgaFd, RGA_IOC_REQUEST_CANCEL, &job_handle) < 0) {
2045         IM_LOGE(" %s(%d) start config fail: %s",__FUNCTION__, __LINE__,strerror(errno));
2046         return IM_STATUS_FAILED;
2047     }
2048 
2049     return IM_STATUS_SUCCESS;
2050 }
2051 
rga_job_submit(im_job_handle_t job_handle,int sync_mode,int acquire_fence_fd,int * release_fence_fd)2052 IM_STATUS rga_job_submit(im_job_handle_t job_handle, int sync_mode, int acquire_fence_fd, int *release_fence_fd) {
2053     int ret;
2054     im_rga_job_t *job = NULL;
2055     struct rga_user_request submit_request;
2056 
2057     if (rga_get_context() != IM_STATUS_SUCCESS)
2058         return IM_STATUS_FAILED;
2059 
2060     g_im2d_job_manager.mutex.lock();
2061 
2062     if (g_im2d_job_manager.job_map.count(job_handle) == 0) {
2063         IM_LOGE("job_handle[%d] is illegal!\n", job_handle);
2064 
2065         g_im2d_job_manager.mutex.unlock();
2066         return IM_STATUS_ILLEGAL_PARAM;
2067     }
2068 
2069     job = g_im2d_job_manager.job_map[job_handle];
2070     if (job == NULL) {
2071         IM_LOGE("job is NULL!\n");
2072 
2073         g_im2d_job_manager.mutex.unlock();
2074         return IM_STATUS_FAILED;
2075     }
2076 
2077     memset(&submit_request, 0x0, sizeof(submit_request));
2078 
2079     submit_request.task_ptr = ptr_to_u64(&job->req);
2080     submit_request.task_num = job->task_count;
2081     submit_request.id = job->id;
2082 
2083     g_im2d_job_manager.job_map.erase(job_handle);
2084     g_im2d_job_manager.job_count--;
2085 
2086     g_im2d_job_manager.mutex.unlock();
2087 
2088     free(job);
2089 
2090     switch (sync_mode) {
2091         case IM_SYNC:
2092             submit_request.sync_mode = RGA_BLIT_SYNC;
2093             break;
2094         case IM_ASYNC:
2095             submit_request.sync_mode = RGA_BLIT_ASYNC;
2096             break;
2097         default:
2098             IM_LOGE("illegal sync mode!\n");
2099             return IM_STATUS_ILLEGAL_PARAM;
2100     }
2101 
2102     submit_request.acquire_fence_fd = acquire_fence_fd;
2103 
2104     ret = ioctl(rgaCtx->rgaFd, RGA_IOC_REQUEST_SUBMIT, &submit_request);
2105     if (ret < 0) {
2106         IM_LOGE(" %s(%d) start config fail: %s",__FUNCTION__, __LINE__,strerror(errno));
2107         return IM_STATUS_FAILED;
2108     }
2109 
2110     if ((sync_mode == IM_ASYNC) && release_fence_fd)
2111         *release_fence_fd = submit_request.release_fence_fd;
2112 
2113     return IM_STATUS_SUCCESS;
2114 }
2115 
rga_job_config(im_job_handle_t job_handle,int sync_mode,int acquire_fence_fd,int * release_fence_fd)2116 IM_STATUS rga_job_config(im_job_handle_t job_handle, int sync_mode, int acquire_fence_fd, int *release_fence_fd) {
2117     int ret;
2118     im_rga_job_t *job = NULL;
2119     struct rga_user_request config_request;
2120 
2121     if (rga_get_context() != IM_STATUS_SUCCESS)
2122         return IM_STATUS_FAILED;
2123 
2124     g_im2d_job_manager.mutex.lock();
2125 
2126     if (g_im2d_job_manager.job_map.count(job_handle) == 0) {
2127         IM_LOGE("job_handle[%d] is illegal!\n", job_handle);
2128 
2129         g_im2d_job_manager.mutex.unlock();
2130         return IM_STATUS_ILLEGAL_PARAM;
2131     }
2132 
2133     job = g_im2d_job_manager.job_map[job_handle];
2134     if (job == NULL) {
2135         IM_LOGE("job is NULL!\n");
2136 
2137         g_im2d_job_manager.mutex.unlock();
2138         return IM_STATUS_FAILED;
2139     }
2140 
2141     memset(&config_request, 0x0, sizeof(config_request));
2142 
2143     config_request.task_ptr = ptr_to_u64(&job->req);
2144     config_request.task_num = job->task_count;
2145     config_request.id = job->id;
2146 
2147     g_im2d_job_manager.mutex.unlock();
2148 
2149     switch (sync_mode) {
2150         case IM_SYNC:
2151             config_request.sync_mode = RGA_BLIT_SYNC;
2152             break;
2153         case IM_ASYNC:
2154             config_request.sync_mode = RGA_BLIT_ASYNC;
2155             break;
2156         default:
2157             IM_LOGE("illegal sync mode!\n");
2158             return IM_STATUS_ILLEGAL_PARAM;
2159     }
2160 
2161     config_request.acquire_fence_fd = acquire_fence_fd;
2162 
2163     ret = ioctl(rgaCtx->rgaFd, RGA_IOC_REQUEST_CONFIG, &config_request);
2164     if (ret < 0) {
2165         IM_LOGE(" %s(%d) start config fail: %s",__FUNCTION__, __LINE__,strerror(errno));
2166         return IM_STATUS_FAILED;
2167     }
2168 
2169     if ((sync_mode == IM_ASYNC) && release_fence_fd)
2170         *release_fence_fd = config_request.release_fence_fd;
2171 
2172     return IM_STATUS_SUCCESS;
2173 }
2174