exynos: remove kernel headers
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos.git] / libfimg4x / FimgApi.cpp
CommitLineData
5763fb39
T
1/*
2**
3** Copyright 2009 Samsung Electronics Co, Ltd.
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16**
17**
18*/
19
20#define LOG_NDEBUG 0
21#define LOG_TAG "SKIA"
22#include <utils/Log.h>
23
24#include "FimgApi.h"
25
26pthread_mutex_t s_g2d_lock = PTHREAD_MUTEX_INITIALIZER;
27
28struct blitinfo_table optbl[] = {
29 { (int)BLIT_OP_SOLID_FILL, "FILL" },
30 { (int)BLIT_OP_CLR, "CLR" },
31 { (int)BLIT_OP_SRC, "SRC" },
32 { (int)BLIT_OP_DST, "DST" },
33 { (int)BLIT_OP_SRC_OVER, "SRC_OVER" },
34 { (int)BLIT_OP_DST_OVER, "DST_OVER" },
35 { (int)BLIT_OP_SRC_IN, "SRC_IN" },
36 { (int)BLIT_OP_DST_IN, "DST_IN" },
37 { (int)BLIT_OP_SRC_OUT, "SRC_OUT" },
38 { (int)BLIT_OP_DST_OUT, "DST_OUT" },
39 { (int)BLIT_OP_SRC_ATOP, "SRC_ATOP" },
40 { (int)BLIT_OP_DST_ATOP, "DST_ATOP" },
41 { (int)BLIT_OP_XOR, "XOR" },
42 { (int)BLIT_OP_ADD, "ADD" },
43 { (int)BLIT_OP_MULTIPLY, "MULTIPLY" },
44 { (int)BLIT_OP_SCREEN, "SCREEN" },
45 { (int)BLIT_OP_DARKEN, "DARKEN" },
46 { (int)BLIT_OP_LIGHTEN, "LIGHTEN" },
47 { (int)BLIT_OP_DISJ_SRC_OVER, "DISJ_SRC_OVER" },
48 { (int)BLIT_OP_DISJ_DST_OVER, "DISJ_DST_OVER" },
49 { (int)BLIT_OP_DISJ_SRC_IN, "DISJ_SRC_IN" },
50 { (int)BLIT_OP_DISJ_DST_IN, "DISJ_DST_IN" },
51 { (int)BLIT_OP_DISJ_SRC_OUT, "DISJ_SRC_OUT" },
52 { (int)BLIT_OP_DISJ_DST_OUT, "DISJ_DST_OUT" },
53 { (int)BLIT_OP_DISJ_SRC_ATOP, "DISJ_SRC_ATOP" },
54 { (int)BLIT_OP_DISJ_DST_ATOP, "DISJ_DST_ATOP" },
55 { (int)BLIT_OP_DISJ_XOR, "DISJ_XOR" },
56 { (int)BLIT_OP_CONJ_SRC_OVER, "CONJ_SRC_OVER" },
57 { (int)BLIT_OP_CONJ_DST_OVER, "CONJ_DST_OVER" },
58 { (int)BLIT_OP_CONJ_SRC_IN, "CONJ_SRC_IN" },
59 { (int)BLIT_OP_CONJ_DST_IN, "CONJ_DST_IN" },
60 { (int)BLIT_OP_CONJ_SRC_OUT, "CONJ_SRC_OUT" },
61 { (int)BLIT_OP_CONJ_DST_OUT, "CONJ_DST_OUT" },
62 { (int)BLIT_OP_CONJ_SRC_ATOP, "CONJ_SRC_ATOP" },
63 { (int)BLIT_OP_CONJ_DST_ATOP, "CONJ_DST_ATOP" },
64 { (int)BLIT_OP_CONJ_XOR, "CONJ_XOR" },
65 { (int)BLIT_OP_USER_COEFF, "USER_COEFF" },
66 { (int)BLIT_OP_END, "" },
67};
68
69struct blitinfo_table repeat_tbl[] = {
70 { (int)NO_REPEAT, "NON" },
71 { (int)REPEAT_NORMAL, "DEFAULT" },
72 { (int)REPEAT_PAD, "PAD" },
73 { (int)REPEAT_REFLECT, "REFLECT, MIRROR" },
74 { (int)REPEAT_CLAMP, "CLAMP" },
75};
76
77#ifndef REAL_DEBUG
78 void VOID_FUNC(const char *format, ...)
79 {}
80#endif
81
82FimgApi::FimgApi()
83{
84 m_flagCreate = false;
85}
86
87FimgApi::~FimgApi()
88{
89 if (m_flagCreate == true)
90 PRINT("%s::this is not Destroyed fail\n", __func__);
91}
92
93bool FimgApi::Create(void)
94{
95 bool ret = false;
96
97 if (t_Lock() == false) {
98 PRINT("%s::t_Lock() fail\n", __func__);
99 goto CREATE_DONE;
100 }
101
102 if (m_flagCreate == true) {
103 PRINT("%s::Already Created fail\n", __func__);
104 goto CREATE_DONE;
105 }
106
107 if (t_Create() == false) {
108 PRINT("%s::t_Create() fail\n", __func__);
109 goto CREATE_DONE;
110 }
111
112 m_flagCreate = true;
113
114 ret = true;
115
116CREATE_DONE :
117
118 t_UnLock();
119
120 return ret;
121}
122
123bool FimgApi::Destroy(void)
124{
125 bool ret = false;
126
127 if (t_Lock() == false) {
128 PRINT("%s::t_Lock() fail\n", __func__);
129 goto DESTROY_DONE;
130 }
131
132 if (m_flagCreate == false) {
133 PRINT("%s::Already Destroyed fail\n", __func__);
134 goto DESTROY_DONE;
135 }
136
137 if (t_Destroy() == false) {
138 PRINT("%s::t_Destroy() fail\n", __func__);
139 goto DESTROY_DONE;
140 }
141
142 m_flagCreate = false;
143
144 ret = true;
145
146DESTROY_DONE :
147
148 t_UnLock();
149
150 return ret;
151}
152
153bool FimgApi::Stretch(struct fimg2d_blit *cmd)
154{
155 bool ret = false;
156
157 if (t_Lock() == false) {
158 PRINT("%s::t_Lock() fail\n", __func__);
159 goto STRETCH_DONE;
160 }
161
162 if (m_flagCreate == false) {
163 PRINT("%s::This is not Created fail\n", __func__);
164 goto STRETCH_DONE;
165 }
166
167 if (t_Stretch(cmd) == false) {
168 goto STRETCH_DONE;
169 }
170
171 ret = true;
172
173STRETCH_DONE :
174
175 t_UnLock();
176
177 return ret;
178}
179
180bool FimgApi::Sync(void)
181{
182 bool ret = false;
183
184 if (m_flagCreate == false) {
185 PRINT("%s::This is not Created fail\n", __func__);
186 goto SYNC_DONE;
187 }
188
189 if (t_Sync() == false)
190 goto SYNC_DONE;
191
192 ret = true;
193
194SYNC_DONE :
195
196 return ret;
197}
198
199bool FimgApi::t_Create(void)
200{
201 PRINT("%s::This is empty virtual function fail\n", __func__);
202 return false;
203}
204
205bool FimgApi::t_Destroy(void)
206{
207 PRINT("%s::This is empty virtual function fail\n", __func__);
208 return false;
209}
210
211bool FimgApi::t_Stretch(struct fimg2d_blit *cmd)
212{
213 PRINT("%s::This is empty virtual function fail\n", __func__);
214 return false;
215}
216
217bool FimgApi::t_Sync(void)
218{
219 PRINT("%s::This is empty virtual function fail\n", __func__);
220 return false;
221}
222
223bool FimgApi::t_Lock(void)
224{
225 PRINT("%s::This is empty virtual function fail\n", __func__);
226 return false;
227}
228
229bool FimgApi::t_UnLock(void)
230{
231 PRINT("%s::This is empty virtual function fail\n", __func__);
232 return false;
233}
234
235//---------------------------------------------------------------------------//
236// extern function
237//---------------------------------------------------------------------------//
238extern "C" int stretchFimgApi(struct fimg2d_blit *cmd)
239{
240 pthread_mutex_lock(&s_g2d_lock);
241
242 FimgApi * fimgApi = createFimgApi();
243
244 if (fimgApi == NULL) {
245 PRINT("%s::createFimgApi() fail\n", __func__);
246 pthread_mutex_unlock(&s_g2d_lock);
247 return -1;
248 }
249
250 if (fimgApi->Stretch(cmd) == false) {
251 if (fimgApi != NULL)
252 destroyFimgApi(fimgApi);
253
254 pthread_mutex_unlock(&s_g2d_lock);
255 return -1;
256 }
257
258 if (fimgApi != NULL)
259 destroyFimgApi(fimgApi);
260
261 pthread_mutex_unlock(&s_g2d_lock);
262 return 0;
263}
264
265extern "C" int stretchFimgApi_fast(struct fimg2d_blit *cmd, unsigned long tmpbuf_addr, int tmpbuf_size)
266{
267 if (tmpbuf_addr == 0 || tmpbuf_size <= 0)
268 return stretchFimgApi(cmd);
269
270 /* scaling & rotation only */
271 if (cmd->param.rotate == ORIGIN || cmd->param.scaling.mode == NO_SCALING)
272 return stretchFimgApi(cmd);
273
274 /* src & dst only */
275 if (cmd->src == NULL || cmd->msk != NULL)
276 return stretchFimgApi(cmd);
277
278 /* a(x)rgb8888 src only */
279 if (cmd->src->fmt >= CF_RGB_565)
280 return stretchFimgApi(cmd);
281
282 FimgApi * fimgApi = createFimgApi();
283
284 if (fimgApi == NULL) {
285 PRINT("%s::createFimgApi() fail\n", __func__);
286 return -1;
287 }
288
289 bool is_scaledown, sr_w, sr_h;
290 struct fimg2d_image tmpbuf;
291 struct fimg2d_blit cmd1st, cmd2nd;
292 struct fimg2d_param *p;
293
294 /* check is_scaledown */
295 p = &cmd->param;
296 sr_w = p->scaling.src_w - p->scaling.dst_w;
297 sr_h = p->scaling.src_h - p->scaling.dst_h;
298 is_scaledown = (sr_w + sr_h > 0) ? true : false;
299
300 if (is_scaledown) {
301 /* set temp buffer */
302 tmpbuf.width = cmd->dst->rect.y2 - cmd->dst->rect.y1;
303 tmpbuf.height = cmd->dst->rect.x2 - cmd->dst->rect.x1;
304 tmpbuf.stride = tmpbuf.width * 4;
305 tmpbuf.order = cmd->src->order;
306 tmpbuf.fmt = cmd->src->fmt;
307 tmpbuf.addr.type = cmd->src->addr.type;
308 tmpbuf.addr.start = tmpbuf_addr;
309 tmpbuf.plane2.type = ADDR_NONE;
310 tmpbuf.rect.x1 = 0;
311 tmpbuf.rect.y1 = 0;
312 tmpbuf.rect.x2 = tmpbuf.width;
313 tmpbuf.rect.y2 = tmpbuf.height;
314 tmpbuf.need_cacheopr = false;
315
316 /* 1st step : copy with scaling down */
317 p = &cmd1st.param;
318 memcpy(p, &cmd->param, sizeof(cmd->param));
319 p->rotate = ORIGIN;
320 p->g_alpha = 0xff;
321 p->dither = false;
322 cmd1st.op = BLIT_OP_SRC;
323 cmd1st.src = cmd->src;
324 cmd1st.dst = &tmpbuf;
325 cmd1st.msk = NULL;
326 cmd1st.tmp = NULL;
327 cmd1st.sync = BLIT_SYNC;
328 cmd1st.seq_no = cmd->seq_no;
329
330 /* 2nd step : op with rotation */
331 p = &cmd2nd.param;
332 memcpy(p, &cmd->param, sizeof(cmd->param));
333 p->scaling.mode = NO_SCALING;
334 cmd2nd.op = cmd->op;
335 cmd2nd.src = &tmpbuf;
336 cmd2nd.dst = cmd->dst;
337 cmd2nd.msk = NULL;
338 cmd2nd.tmp = NULL;
339 cmd2nd.sync = BLIT_SYNC;
340 cmd2nd.seq_no = cmd->seq_no;
341 } else {
342 /* set temp buffer */
343 tmpbuf.width = cmd->src->rect.y2 - cmd->src->rect.y1;
344 tmpbuf.height = cmd->src->rect.x2 - cmd->src->rect.x1;
345 tmpbuf.stride = tmpbuf.width * 4;
346 tmpbuf.order = cmd->src->order;
347 tmpbuf.fmt = cmd->src->fmt;
348 tmpbuf.addr.type = cmd->src->addr.type;
349 tmpbuf.addr.start = tmpbuf_addr;
350 tmpbuf.plane2.type = ADDR_NONE;
351 tmpbuf.rect.x1 = 0;
352 tmpbuf.rect.y1 = 0;
353 tmpbuf.rect.x2 = tmpbuf.width;
354 tmpbuf.rect.y2 = tmpbuf.height;
355 tmpbuf.need_cacheopr = false;
356
357 /* 1st step : copy with rotation */
358 p = &cmd1st.param;
359 memcpy(p, &cmd->param, sizeof(cmd->param));
360 p->scaling.mode = NO_SCALING;
361 p->g_alpha = 0xff;
362 p->dither = false;
363 cmd1st.op = BLIT_OP_SRC;
364 cmd1st.src = cmd->src;
365 cmd1st.dst = &tmpbuf;
366 cmd1st.msk = NULL;
367 cmd1st.tmp = NULL;
368 cmd1st.sync = BLIT_SYNC;
369 cmd1st.seq_no = cmd->seq_no;
370
371 /* 2nd step : op with scaling up */
372 p = &cmd2nd.param;
373 memcpy(p, &cmd->param, sizeof(cmd->param));
374 p->rotate = ORIGIN;
375 cmd2nd.op = cmd->op;
376 cmd2nd.src = &tmpbuf;
377 cmd2nd.dst = cmd->dst;
378 cmd2nd.msk = NULL;
379 cmd2nd.tmp = NULL;
380 cmd2nd.sync = BLIT_SYNC;
381 cmd2nd.seq_no = cmd->seq_no;
382 }
383
384 /* 1st step blit */
385 if (fimgApi->Stretch(&cmd1st) == false) {
386 if (fimgApi != NULL)
387 destroyFimgApi(fimgApi);
388 return -1;
389 }
390
391 /* 2nd step blit */
392 if (fimgApi->Stretch(&cmd2nd) == false) {
393 if (fimgApi != NULL)
394 destroyFimgApi(fimgApi);
395 return -1;
396 }
397
398 if (fimgApi != NULL)
399 destroyFimgApi(fimgApi);
400
401 return 0;
402}
403
404extern "C" int SyncFimgApi(void)
405{
406 pthread_mutex_lock(&s_g2d_lock);
407 FimgApi * fimgApi = createFimgApi();
408 if (fimgApi == NULL) {
409 PRINT("%s::createFimgApi() fail\n", __func__);
410 pthread_mutex_unlock(&s_g2d_lock);
411 return -1;
412 }
413
414 if (fimgApi->Sync() == false) {
415 if (fimgApi != NULL)
416 destroyFimgApi(fimgApi);
417
418 pthread_mutex_unlock(&s_g2d_lock);
419 return -1;
420 }
421
422 if (fimgApi != NULL)
423 destroyFimgApi(fimgApi);
424
425 pthread_mutex_unlock(&s_g2d_lock);
426 return 0;
427}
428
429void printDataBlit(char *title, const char *called, struct fimg2d_blit *cmd)
430{
431 SLOGI("%s (From %s)\n", title, called);
432 SLOGI(" sequence_no. = %u\n", cmd->seq_no);
433 SLOGI(" blit_op = %d(%s)\n", cmd->op, optbl[cmd->op].str);
434 SLOGI(" fill_color = %X\n", cmd->param.solid_color);
435 SLOGI(" global_alpha = %u\n", (unsigned int)cmd->param.g_alpha);
436 SLOGI(" PREMULT = %s\n", cmd->param.premult == PREMULTIPLIED ? "PREMULTIPLIED" : "NON-PREMULTIPLIED");
437 SLOGI(" do_dither = %s\n", cmd->param.dither == true ? "dither" : "no-dither");
438 SLOGI(" repeat = %d(%s)\n", cmd->param.repeat.mode,
439 repeat_tbl[cmd->param.repeat.mode].str);
440
441 printDataBlitRotate(cmd->param.rotate);
442
443 printDataBlitScale(&cmd->param.scaling);
444
445 printDataBlitImage("SRC", cmd->src);
446 printDataBlitImage("DST", cmd->dst);
447
448 if (cmd->src != NULL)
449 printDataBlitRect("SRC", &cmd->src->rect);
450 if (cmd->dst != NULL)
451 printDataBlitRect("DST", &cmd->dst->rect);
452}
453
454void printDataBlitImage(const char *title, struct fimg2d_image *image)
455{
456 if (NULL != image) {
457 SLOGI(" Image_%s\n", title);
458 SLOGI(" addr = %X\n", image->addr.start);
459 SLOGI(" format = %d\n", image->fmt);
460 SLOGI(" size = (%d, %d)\n", image->width, image->height);
461 } else {
462 SLOGI(" Image_%s : NULL\n", title);
463 }
464}
465
466void printDataBlitRect(const char *title, struct fimg2d_rect *rect)
467{
468 if (NULL != rect) {
469 SLOGI(" RECT_%s\n", title);
470 SLOGI(" (x1, y1) = (%d, %d)\n", rect->x1, rect->y1);
471 SLOGI(" (x2, y2) = (%d, %d)\n", rect->x2, rect->y2);
472 SLOGI(" (width, height) = (%d, %d)\n", rect->x2 - rect->x1, rect->y2 - rect->y1);
473 } else
474 SLOGI(" RECT_%s : NULL\n", title);
475}
476
477void printDataBlitRotate(int rotate)
478{
479 SLOGI(" ROTATE : %d\n", rotate);
480}
481
482void printDataBlitScale(struct fimg2d_scale *scaling)
483{
484 SLOGI(" SCALING\n");
485 if (scaling->mode != 0) {
486 SLOGI(" scale_mode : %s\n", (scaling->mode == 1 ? "SCALING_NEAREST" : "SCALING_BILINEAR"));
487 SLOGI(" src : (src_w, src_h) = (%d, %d)\n", scaling->src_w, scaling->src_h);
488 SLOGI(" dst : (dst_w, dst_h) = (%d, %d)\n", scaling->dst_w, scaling->dst_h);
489 SLOGI(" scaling_factor : (scale_w, scale_y) = (%3.2f, %3.2f)\n",
490 (double)scaling->dst_w / scaling->src_w, (double)scaling->dst_h / scaling->src_h);
491 } else {
492 SLOGI(" scale_mode : NO_SCALING\n");
493 }
494}