import exynos 7570 bsp
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos.git] / libfimg5x / FimgApi.cpp
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
26 #ifdef FIMG2D_USE_M2M1SHOT2
27 #include "videodev2.h"
28 #include <linux/m2m1shot2.h>
29
30 /* include freq leveling and compromise table */
31 #include "sec_g2d_comp.h"
32 unsigned int fmt_m2m1shot1_format[] = {
33 V4L2_PIX_FMT_RGB565,
34 V4L2_PIX_FMT_ARGB32,
35 V4L2_PIX_FMT_ABGR32,
36 };
37
38 unsigned int xfer_m2m1shot2_format[] = {
39 M2M1SHOT2_BLEND_CLEAR,
40 M2M1SHOT2_BLEND_SRC,
41 M2M1SHOT2_BLEND_DST,
42 M2M1SHOT2_BLEND_SRCOVER,
43 };
44
45 unsigned int filter_m2m1shot2_format[] = {
46 M2M1SHOT2_SCFILTER_BILINEAR,
47 M2M1SHOT2_SCFILTER_BILINEAR,
48 };
49
50 unsigned int repeat_m2m1shot2_format[] = {
51 M2M1SHOT2_REPEAT_CLAMP,
52 M2M1SHOT2_REPEAT_REPEAT,
53 M2M1SHOT2_REPEAT_REFLECT,
54 M2M1SHOT2_REPEAT_NONE,
55 };
56 #endif
57
58 pthread_mutex_t s_g2d_lock = PTHREAD_MUTEX_INITIALIZER;
59
60 struct blitinfo_table optbl[] = {
61 { (int)BLIT_OP_NONE, "NONE" },
62 { (int)BLIT_OP_SOLID_FILL, "FILL" },
63 { (int)BLIT_OP_CLR, "CLR" },
64 { (int)BLIT_OP_SRC, "SRC" },
65 { (int)BLIT_OP_DST, "DST" },
66 { (int)BLIT_OP_SRC_OVER, "SRC_OVER" },
67 { (int)BLIT_OP_DST_OVER, "DST_OVER" },
68 { (int)BLIT_OP_SRC_IN, "SRC_IN" },
69 { (int)BLIT_OP_DST_IN, "DST_IN" },
70 { (int)BLIT_OP_SRC_OUT, "SRC_OUT" },
71 { (int)BLIT_OP_DST_OUT, "DST_OUT" },
72 { (int)BLIT_OP_SRC_ATOP, "SRC_ATOP" },
73 { (int)BLIT_OP_DST_ATOP, "DST_ATOP" },
74 { (int)BLIT_OP_XOR, "XOR" },
75 { (int)BLIT_OP_ADD, "ADD" },
76 { (int)BLIT_OP_MULTIPLY, "MULTIPLY" },
77 { (int)BLIT_OP_SCREEN, "SCREEN" },
78 { (int)BLIT_OP_DARKEN, "DARKEN" },
79 { (int)BLIT_OP_LIGHTEN, "LIGHTEN" },
80 { (int)BLIT_OP_DISJ_SRC_OVER, "DISJ_SRC_OVER" },
81 { (int)BLIT_OP_DISJ_DST_OVER, "DISJ_DST_OVER" },
82 { (int)BLIT_OP_DISJ_SRC_IN, "DISJ_SRC_IN" },
83 { (int)BLIT_OP_DISJ_DST_IN, "DISJ_DST_IN" },
84 { (int)BLIT_OP_DISJ_SRC_OUT, "DISJ_SRC_OUT" },
85 { (int)BLIT_OP_DISJ_DST_OUT, "DISJ_DST_OUT" },
86 { (int)BLIT_OP_DISJ_SRC_ATOP, "DISJ_SRC_ATOP" },
87 { (int)BLIT_OP_DISJ_DST_ATOP, "DISJ_DST_ATOP" },
88 { (int)BLIT_OP_DISJ_XOR, "DISJ_XOR" },
89 { (int)BLIT_OP_CONJ_SRC_OVER, "CONJ_SRC_OVER" },
90 { (int)BLIT_OP_CONJ_DST_OVER, "CONJ_DST_OVER" },
91 { (int)BLIT_OP_CONJ_SRC_IN, "CONJ_SRC_IN" },
92 { (int)BLIT_OP_CONJ_DST_IN, "CONJ_DST_IN" },
93 { (int)BLIT_OP_CONJ_SRC_OUT, "CONJ_SRC_OUT" },
94 { (int)BLIT_OP_CONJ_DST_OUT, "CONJ_DST_OUT" },
95 { (int)BLIT_OP_CONJ_SRC_ATOP, "CONJ_SRC_ATOP" },
96 { (int)BLIT_OP_CONJ_DST_ATOP, "CONJ_DST_ATOP" },
97 { (int)BLIT_OP_CONJ_XOR, "CONJ_XOR" },
98 { (int)BLIT_OP_USER_COEFF, "USER_COEFF" },
99 { (int)BLIT_OP_END, "" },
100 };
101
102 struct blitinfo_table repeat_tbl[] = {
103 { (int)NO_REPEAT, "NON" },
104 { (int)REPEAT_NORMAL, "DEFAULT" },
105 { (int)REPEAT_PAD, "PAD" },
106 { (int)REPEAT_REFLECT, "REFLECT, MIRROR" },
107 { (int)REPEAT_CLAMP, "CLAMP" },
108 };
109
110 #ifndef REAL_DEBUG
111 void VOID_FUNC(__attribute__((__unused__)) const char *format, ...)
112 {}
113 #endif
114
115 FimgApi::FimgApi()
116 {
117 m_flagCreate = false;
118 }
119
120 FimgApi::~FimgApi()
121 {
122 if (m_flagCreate == true)
123 PRINT("%s::this is not Destroyed fail\n", __func__);
124 }
125
126 bool FimgApi::Create(void)
127 {
128 bool ret = false;
129
130 if (t_Lock() == false) {
131 PRINT("%s::t_Lock() fail\n", __func__);
132 goto CREATE_DONE;
133 }
134
135 if (m_flagCreate == true) {
136 PRINT("%s::Already Created fail\n", __func__);
137 goto CREATE_DONE;
138 }
139
140 if (t_Create() == false) {
141 PRINT("%s::t_Create() fail\n", __func__);
142 goto CREATE_DONE;
143 }
144
145 m_flagCreate = true;
146
147 ret = true;
148
149 CREATE_DONE :
150
151 t_UnLock();
152
153 return ret;
154 }
155
156 bool FimgApi::Destroy(void)
157 {
158 bool ret = false;
159
160 if (t_Lock() == false) {
161 PRINT("%s::t_Lock() fail\n", __func__);
162 goto DESTROY_DONE;
163 }
164
165 if (m_flagCreate == false) {
166 PRINT("%s::Already Destroyed fail\n", __func__);
167 goto DESTROY_DONE;
168 }
169
170 if (t_Destroy() == false) {
171 PRINT("%s::t_Destroy() fail\n", __func__);
172 goto DESTROY_DONE;
173 }
174
175 m_flagCreate = false;
176
177 ret = true;
178
179 DESTROY_DONE :
180
181 t_UnLock();
182
183 return ret;
184 }
185 #ifdef FIMG2D_USE_M2M1SHOT2
186 bool FimgApi::Stretch_v5(struct m2m1shot2 *cmd)
187 {
188 bool ret = false;
189
190 if (t_Lock() == false) {
191 PRINT("%s::t_Lock() fail\n", __func__);
192 goto STRETCH_DONE;
193 }
194
195 if (m_flagCreate == false) {
196 PRINT("%s::This is not Created fail\n", __func__);
197 goto STRETCH_DONE;
198 }
199
200 if (t_Stretch_v5(cmd) == false) {
201 goto STRETCH_DONE;
202 }
203
204 ret = true;
205
206 STRETCH_DONE :
207
208 t_UnLock();
209
210 return ret;
211 }
212 #endif
213 bool FimgApi::Stretch(struct fimg2d_blit *cmd)
214 {
215 bool ret = false;
216
217 if (t_Lock() == false) {
218 PRINT("%s::t_Lock() fail\n", __func__);
219 goto STRETCH_DONE;
220 }
221
222 if (m_flagCreate == false) {
223 PRINT("%s::This is not Created fail\n", __func__);
224 goto STRETCH_DONE;
225 }
226
227 if (t_Stretch(cmd) == false) {
228 goto STRETCH_DONE;
229 }
230
231 ret = true;
232
233 STRETCH_DONE :
234
235 t_UnLock();
236
237 return ret;
238 }
239
240 bool FimgApi::Sync(void)
241 {
242 bool ret = false;
243
244 if (m_flagCreate == false) {
245 PRINT("%s::This is not Created fail\n", __func__);
246 goto SYNC_DONE;
247 }
248
249 if (t_Sync() == false)
250 goto SYNC_DONE;
251
252 ret = true;
253
254 SYNC_DONE :
255
256 return ret;
257 }
258
259 bool FimgApi::t_Create(void)
260 {
261 PRINT("%s::This is empty virtual function fail\n", __func__);
262 return false;
263 }
264
265 bool FimgApi::t_Destroy(void)
266 {
267 PRINT("%s::This is empty virtual function fail\n", __func__);
268 return false;
269 }
270
271 bool FimgApi::t_Stretch(__attribute__((__unused__)) struct fimg2d_blit *cmd)
272 {
273 PRINT("%s::This is empty virtual function fail\n", __func__);
274 return false;
275 }
276 #ifdef FIMG2D_USE_M2M1SHOT2
277 bool FimgApi::t_Stretch_v5(__attribute__((__unused__)) struct m2m1shot2 *cmd)
278 {
279 PRINT("%s::This is empty virtual function fail\n", __func__);
280 return false;
281 }
282 #endif
283 bool FimgApi::t_Sync(void)
284 {
285 PRINT("%s::This is empty virtual function fail\n", __func__);
286 return false;
287 }
288
289 bool FimgApi::t_Lock(void)
290 {
291 PRINT("%s::This is empty virtual function fail\n", __func__);
292 return false;
293 }
294
295 bool FimgApi::t_UnLock(void)
296 {
297 PRINT("%s::This is empty virtual function fail\n", __func__);
298 return false;
299 }
300
301 //---------------------------------------------------------------------------//
302 // extern function
303 //---------------------------------------------------------------------------//
304 extern "C" int stretchFimgApi(struct fimg2d_blit *cmd)
305 {
306 pthread_mutex_lock(&s_g2d_lock);
307
308 FimgApi * fimgApi = createFimgApi();
309
310 if (fimgApi == NULL) {
311 PRINT("%s::createFimgApi() fail\n", __func__);
312 pthread_mutex_unlock(&s_g2d_lock);
313 return -1;
314 }
315
316 if (fimgApi->Stretch(cmd) == false) {
317 if (fimgApi != NULL)
318 destroyFimgApi(fimgApi);
319
320 pthread_mutex_unlock(&s_g2d_lock);
321 return -1;
322 }
323
324 if (fimgApi != NULL)
325 destroyFimgApi(fimgApi);
326
327 pthread_mutex_unlock(&s_g2d_lock);
328 return 0;
329 }
330
331 extern "C" int SyncFimgApi(void)
332 {
333 pthread_mutex_lock(&s_g2d_lock);
334 FimgApi * fimgApi = createFimgApi();
335 if (fimgApi == NULL) {
336 PRINT("%s::createFimgApi() fail\n", __func__);
337 pthread_mutex_unlock(&s_g2d_lock);
338 return -1;
339 }
340
341 if (fimgApi->Sync() == false) {
342 if (fimgApi != NULL)
343 destroyFimgApi(fimgApi);
344
345 pthread_mutex_unlock(&s_g2d_lock);
346 return -1;
347 }
348
349 if (fimgApi != NULL)
350 destroyFimgApi(fimgApi);
351
352 pthread_mutex_unlock(&s_g2d_lock);
353 return 0;
354 }
355
356 #ifdef FIMG2D_USE_M2M1SHOT2
357 extern "C" int stretchFimgApi_v5(struct m2m1shot2 *cmd)
358 {
359 pthread_mutex_lock(&s_g2d_lock);
360
361 FimgApi * fimgApi = createFimgApi();
362
363 if (fimgApi == NULL) {
364 PRINT("%s::createFimgApi() fail\n", __func__);
365 pthread_mutex_unlock(&s_g2d_lock);
366 return -1;
367 }
368
369 if (fimgApi->Stretch_v5(cmd) == false) {
370 if (fimgApi != NULL)
371 destroyFimgApi(fimgApi);
372
373 pthread_mutex_unlock(&s_g2d_lock);
374 return -1;
375 }
376
377 if (fimgApi != NULL)
378 destroyFimgApi(fimgApi);
379
380 pthread_mutex_unlock(&s_g2d_lock);
381 return 0;
382 }
383
384 #ifdef FIMGAPI_HAL_FREQLEVELING
385 int FimgApiFreqleveling(Fimg *fimg)
386 {
387 static struct timeval prev;
388 static int prev_level = -1;
389 struct timeval current;
390 unsigned int size = (unsigned int)(fimg->clipR - fimg->clipL) *
391 (unsigned int)(fimg->clipB - fimg->clipT);
392 int result = MIN_LEVEL;
393 unsigned long time = 0;
394
395 gettimeofday(&current, NULL);
396 if ((current.tv_sec - prev.tv_sec) * 1000000 +
397 (current.tv_usec - prev.tv_usec) < 20000 && prev_level != -1) {
398 if (prev_level > 0)
399 prev_level--;
400 prev = current;
401
402 return prev_level;
403 }
404
405 for (int i = 0; i < MIN_LEVEL; i++) {
406 if (fimg_standard_size[i] < size)
407 result = i;
408 }
409 prev = current;
410 prev_level = result;
411
412 #ifdef FIMGAPI_HAL_DEBUG
413 ALOGE("freq leveling : %d", result);
414 #endif
415 return result;
416 }
417 #endif
418
419 #ifdef FIMGAPI_HAL_COMPROMISE
420 bool FimgApiCompromise(Fimg *fimg)
421 {
422 struct compromise_param param;
423
424 /* source format setting*/
425 param.src_fmt = (fimg->srcColorFormat == 0)? 0 : 1;
426 param.dst_fmt = (fimg->dstColorFormat == 0)? 0 : 1;
427
428 /* scaling setting */
429 if (fimg->srcW == fimg->dstW && fimg->srcH == fimg->dstH)
430 param.isScaling = 0;
431 else if (fimg->srcW * fimg->srcH < fimg->dstW * fimg->dstH)
432 param.isScaling = 1;
433 else
434 param.isScaling = 2;
435
436 /* filter_mode setting */
437 param.isFilter = fimg->isFilter;
438
439 /* blending mode setting */
440 if (fimg->xfermode == 1)
441 param.isSrcOver = 0;
442 else if (fimg->xfermode == 3)
443 param.isSrcOver = 1;
444 else
445 return false;
446
447 param.clipW = (fimg->clipR - fimg->clipL) * 1.2;
448 param.clipH = (fimg->clipB - fimg->clipT) * 0.8;
449 #ifdef FIMGAPI_HAL_DEBUG
450 ALOGE("compromise [%d %d %d %d %d] [comp %d and %d]", param.src_fmt, param.dst_fmt,
451 param.isScaling, param.isFilter, param.isSrcOver, param.clipW * param.clipH,
452 comp_value[param.src_fmt][param.dst_fmt][param.isScaling][param.isFilter][param.isSrcOver]);
453 #endif
454
455 if ((param.clipW * param.clipH) < comp_value[param.src_fmt][param.dst_fmt][param.isScaling][param.isFilter][param.isSrcOver])
456 return false;
457 return true;
458 }
459 #endif
460
461 void printDataBlitImage_v5(struct m2m1shot2_image* image)
462 {
463 /* image feature */
464 SLOGI("flags : %u", image->flags);
465 SLOGI("memory : %u", image->memory);
466 /* image.buffer : address and buffer size */
467
468 struct m2m1shot2_buffer &buffer = image->plane[0];
469 SLOGI("address %x", buffer.userptr);
470 SLOGI("length %u", buffer.length);
471
472 /* image.format : color format and coordinate */
473 struct m2m1shot2_format &image_fmt = image->fmt;
474 SLOGI("width : %u", image_fmt.width);
475 SLOGI("height: %u", image_fmt.height);
476 SLOGI("format: %u", image_fmt.pixelformat);
477
478 /* image.format : color format and coordinate */
479 SLOGI("crop : %d, %d (%u x %u)", image_fmt.crop.left,
480 image_fmt.crop.top, image_fmt.crop.width, image_fmt.crop.height);
481 SLOGI("widnow : %d, %d (%u x %u)", image_fmt.window.left,
482 image_fmt.window.top, image_fmt.window.width, image_fmt.window.height);
483 /* image.extra : parameter (only source image) */
484 struct m2m1shot2_extra &extra = image->ext;
485 SLOGI("scaler_filter : %u", extra.scaler_filter);
486 SLOGI("composite : %u",extra.composit_mode);
487 SLOGI("g_alpha : %u", extra.galpha);
488 SLOGI("repeat : %u", extra.xrepeat);
489 }
490
491 void printDataBlit_v5(const char *title, int called, struct m2m1shot2 cmd)
492 {
493 SLOGI("%s (from %d)\n", title, called);
494 SLOGI("cmd flag %x", cmd.flags);
495 SLOGI("- - - - - - - destination - - - - - -");
496 printDataBlitImage_v5(&cmd.target);
497 SLOGI("- - - - - - - destination (source[0]-");
498 printDataBlitImage_v5(&cmd.sources[0]);
499 SLOGI("- - - - - - - source - - - - - - - - ");
500 printDataBlitImage_v5(&cmd.sources[1]);
501 }
502
503 void copy_m2m1shot2_image(struct m2m1shot2_image *dst, struct m2m1shot2_image *src)
504 {
505 /* initialize the image */
506 memset(dst, 0, sizeof(struct m2m1shot2_image));
507
508 /* image feature */
509 dst->flags = src->flags;
510 dst->fence = src->fence;
511 dst->memory = src->memory;
512 dst->num_planes = src->num_planes;
513
514 /* image.buffer : address and buffer size */
515 struct m2m1shot2_buffer &d_buffer = dst->plane[0];
516 struct m2m1shot2_buffer &s_buffer = src->plane[0];
517 d_buffer.userptr = s_buffer.userptr;
518 d_buffer.length = s_buffer.length;
519 d_buffer.offset = s_buffer.offset;
520
521 /* image.format : color format and coordinate */
522 struct m2m1shot2_format &d_format = dst->fmt;
523 struct m2m1shot2_format &s_format = src->fmt;
524 d_format.width = s_format.width;
525 d_format.height = s_format.height;
526 d_format.pixelformat = s_format.pixelformat;
527
528 d_format.crop.left = s_format.crop.left;
529 d_format.crop.top = s_format.crop.top;
530 d_format.crop.width = s_format.crop.width;
531 d_format.crop.height = s_format.crop.height;
532
533 d_format.window.left = s_format.window.left;
534 d_format.window.top = s_format.window.top;
535 d_format.window.width = s_format.window.width;
536 d_format.window.height = s_format.window.height;
537
538 /* image.extra : parameter (only source image) */
539 struct m2m1shot2_extra &d_extra = dst->ext;
540 struct m2m1shot2_extra &s_extra = src->ext;
541 d_extra.scaler_filter = s_extra.scaler_filter;
542 d_extra.fillcolor = s_extra.fillcolor;
543 d_extra.transform = s_extra.transform;
544 d_extra.composit_mode = s_extra.composit_mode;
545 d_extra.galpha_red = d_extra.galpha_green =
546 d_extra.galpha = d_extra.galpha_blue = s_extra.galpha;
547 d_extra.xrepeat = s_extra.xrepeat;
548 d_extra.yrepeat = s_extra.yrepeat;
549 }
550
551 unsigned int scale_factor_to_fixed(float m) {
552 unsigned int value = m * (1 << 16);
553 return value & 0xFFFFFFFF;
554 }
555
556 int requestFimgApi_v5(Fimg *fimg)
557 {
558 struct m2m1shot2 cmd;
559
560 #ifdef FIMGAPI_HAL_COMPROMISE
561 if (FimgApiCompromise(fimg) == false)
562 return -1;
563 #endif
564 #ifdef FIMGAPI_G2D_NEAREST_UNSUPPORT
565 if (fimg->isFilter == false)
566 return -1;
567 #endif
568 /* initialize the command */
569 memset(&cmd, 0, sizeof(cmd));
570 cmd.sources = new m2m1shot2_image[3];
571
572 /* m2m1shot2 */
573 struct m2m1shot2_image &srcImage = cmd.sources[1];
574 struct m2m1shot2_image &dstImage = cmd.sources[0];
575 cmd.num_sources = 2;
576 cmd.flags = (fimg->isDither) & 0x1; /* dither | nonblock | error response */
577
578 /* initialize the image */
579 memset(&srcImage, 0, sizeof(srcImage));
580 memset(&dstImage, 0, sizeof(dstImage));
581
582 /* image feature */
583 srcImage.flags = M2M1SHOT2_IMGFLAG_PREMUL_ALPHA | M2M1SHOT2_IMGFLAG_GLOBAL_ALPHA;
584 srcImage.fence = 0; /* no use */
585 srcImage.memory = M2M1SHOT2_BUFTYPE_USERPTR;
586 srcImage.num_planes = 1;
587
588 /* image.buffer : address and buffer size */
589 struct m2m1shot2_buffer &s_buffer = srcImage.plane[0];
590 s_buffer.userptr = (unsigned long) fimg->srcAddr;
591 s_buffer.length = s_buffer.payload = fimg->srcFH * fimg->srcFWStride;
592 s_buffer.offset = 0;
593
594 /* image.format : color format and coordinate */
595 struct m2m1shot2_format &s_format = srcImage.fmt;
596 s_format.width = fimg->srcFWStride / fimg->srcBPP;
597 s_format.height = fimg->srcFH;
598 s_format.pixelformat = fmt_m2m1shot1_format[fimg->srcColorFormat];
599
600 s_format.crop.left = fimg->srcX;
601 s_format.crop.top = fimg->srcY;
602 s_format.crop.width = fimg->srcW;
603 s_format.crop.height = fimg->srcH;
604
605 s_format.window.left = fimg->dstX;
606 s_format.window.top = fimg->dstY;
607 s_format.window.width = fimg->dstW;
608 s_format.window.height = fimg->dstH;
609
610 /* image.extra : parameter (only source image) */
611 struct m2m1shot2_extra &s_extra = srcImage.ext;
612 if (fimg->matrixSw != 1.0f || fimg->matrixSh != 1.0f) {
613 /* caculate factor and enable factor */
614 /* or not, draw from source size to destination size */
615 s_extra.scaler_filter = M2M1SHOT2_SCFILTER_BILINEAR;
616 /* set the scaling ratio */
617 float Sw = 1.0f / fimg->matrixSw;
618 float Sh = 1.0f / fimg->matrixSh;
619 s_extra.horizontal_factor = scale_factor_to_fixed(Sw);
620 s_extra.vertical_factor = scale_factor_to_fixed(Sh);
621 srcImage.flags |= M2M1SHOT2_IMGFLAG_XSCALE_FACTOR;
622 srcImage.flags |= M2M1SHOT2_IMGFLAG_YSCALE_FACTOR;
623 } else {
624 s_extra.scaler_filter = M2M1SHOT2_SCFILTER_NONE;
625 cmd.flags |= M2M1SHOT2_IMGFLAG_NO_RESCALING;
626 }
627
628 s_extra.fillcolor = fimg->fillcolor;
629 s_extra.transform = 0;
630 s_extra.composit_mode = xfer_m2m1shot2_format[fimg->xfermode];
631 s_extra.galpha_red = s_extra.galpha_green =
632 s_extra.galpha_blue = s_extra.galpha = fimg->alpha;
633 s_extra.xrepeat = s_extra.yrepeat = repeat_m2m1shot2_format[fimg->tileModeX];
634
635 /* image feature */
636 dstImage.flags = M2M1SHOT2_IMGFLAG_PREMUL_ALPHA;
637 dstImage.fence = 0;
638 dstImage.memory = M2M1SHOT2_BUFTYPE_USERPTR;
639 dstImage.num_planes = 1;
640
641 /* image.buffer : address and buffer size */
642 struct m2m1shot2_buffer &d_buffer = dstImage.plane[0];
643 d_buffer.userptr = (unsigned long) fimg->dstAddr;
644 d_buffer.length = d_buffer.payload = fimg->dstFH * fimg->dstFWStride;
645 d_buffer.offset = 0;
646
647 /* image.format : color format and coordinate */
648 struct m2m1shot2_format &d_format = dstImage.fmt;
649 d_format.width = fimg->dstFWStride / fimg->dstBPP;
650 d_format.height = fimg->dstFH;
651 d_format.pixelformat = fmt_m2m1shot1_format[fimg->dstColorFormat];
652
653 d_format.crop.left = d_format.window.left = fimg->clipL;
654 d_format.crop.top = d_format.window.top = fimg->clipT;
655 d_format.crop.width = d_format.window.width = fimg->clipR - fimg->clipL;
656 d_format.crop.height = d_format.window.height = fimg->clipB - fimg->clipT;
657
658 /* image.extra : parameter (only source image) */
659 struct m2m1shot2_extra &d_extra = dstImage.ext;
660 d_extra.scaler_filter = M2M1SHOT2_SCFILTER_NONE;
661 d_extra.fillcolor = fimg->fillcolor;
662 d_extra.transform = 0;
663 d_extra.composit_mode = M2M1SHOT2_BLEND_NONE;
664 d_extra.galpha_red = d_extra.galpha_green =
665 d_extra.galpha = d_extra.galpha_blue = 0x0;
666 d_extra.xrepeat = d_extra.yrepeat = M2M1SHOT2_REPEAT_NONE;
667
668 copy_m2m1shot2_image(&cmd.target, &dstImage);
669 /* src img[0] need to set xfermode::src for drawing dst */
670 d_extra.composit_mode = M2M1SHOT2_BLEND_SRC;
671
672 /* freq supports 4 level as frequency and size*/
673 #ifdef FIMGAPI_HAL_FREQLEVELING
674 static int prev_level[4];
675 static int level_count = -1;
676 static int current_level = 4;
677 int level;
678
679 level = FimgApiFreqleveling(fimg);
680 if (level_count == -1) {
681 for (int i = 0; i < 4; i++)
682 prev_level[i] = 4;
683 level_count++;
684 }
685 prev_level[level_count % 4] = level;
686 level_count++;
687 fimg->level = prev_level[0];
688 for (int i = 1; i < 4; i++) {
689 if (prev_level[i] < fimg->level)
690 fimg->level = prev_level[i];
691 }
692 #endif
693
694 #ifdef FIMGAPI_HAL_DEBUG
695 printDataBlit_v5(__func__, fimg->called, cmd);
696 #endif
697 /* if it does not success, need to debug */
698 if (stretchFimgApi_v5(&cmd) < 0) {
699 ALOGE("%s : g2d hardware operation failed", __func__);
700 return -1;
701 }
702
703 return 0;
704 }
705 #endif
706 void printDataBlit(char *title, const char *called, struct fimg2d_blit *cmd)
707 {
708 struct fimg2d_image *srcImage;
709 struct fimg2d_image *dstImage;
710 struct fimg2d_param *srcParam;
711 srcImage = cmd->src[1];
712 dstImage = cmd->dst;
713 srcParam = &srcImage->param;
714
715 SLOGI("%s (From %s)\n", title, called);
716 SLOGI(" sequence_no. = %u\n", cmd->seq_no);
717 SLOGI(" blit_op = %d(%s)\n", srcImage->op, optbl[srcImage->op].str);
718 SLOGI(" fill_color = %X\n", srcParam->solid_color);
719 SLOGI(" global_alpha = %u\n", (unsigned int)srcParam->g_alpha);
720 SLOGI(" PREMULT = %s\n", srcParam->premult == PREMULTIPLIED ? "PREMULTIPLIED" : "NON-PREMULTIPLIED");
721 SLOGI(" do_dither = %s\n", cmd->dither == true ? "dither" : "no-dither");
722 SLOGI(" repeat = %d(%s)\n", srcParam->repeat.mode,
723 repeat_tbl[srcParam->repeat.mode].str);
724
725 printDataBlitRotate(srcParam->rotate);
726
727 printDataBlitScale(&srcParam->scaling);
728
729 printDataBlitImage("SRC", srcImage);
730 printDataBlitImage("DST", dstImage);
731
732 if (srcImage != NULL)
733 printDataBlitRect("SRC", &srcImage->rect);
734 if (srcParam != NULL)
735 printDataBlitRect("SRC_CLIP(same as DST)", &srcParam->clipping);
736 if (dstImage != NULL)
737 printDataBlitRect("DST_CLIP", &dstImage->rect);
738 }
739
740 void printDataBlitImage(const char *title, struct fimg2d_image *image)
741 {
742 if (NULL != image) {
743 SLOGI(" Image_%s\n", title);
744 SLOGI(" addr = %lx\n", image->addr.start);
745 SLOGI(" format = %s\n", image->fmt == 0 ? "ARGB_8888" : "RGB_565");
746 SLOGI(" size = (%d, %d)\n", image->width, image->height);
747 } else {
748 SLOGI(" Image_%s : NULL\n", title);
749 }
750 }
751
752 void printDataBlitRect(const char *title, struct fimg2d_clip *clipping)
753 {
754 if (NULL != clipping && clipping->enable == 1) {
755 SLOGI(" RECT_%s\n", title);
756 SLOGI(" (x1, y1) = (%d, %d)\n", clipping->x1, clipping->y1);
757 SLOGI(" (x2, y2) = (%d, %d)\n", clipping->x2, clipping->y2);
758 SLOGI(" (width, height) = (%d, %d)\n", clipping->x2 - clipping->x1, clipping->y2 - clipping->y1);
759 } else {
760 SLOGI(" RECT_%s : NULL\n", title);
761 }
762 }
763
764 void printDataBlitRect(const char *title, struct fimg2d_rect *rect)
765 {
766 if (NULL != rect) {
767 SLOGI(" RECT_%s\n", title);
768 SLOGI(" (x1, y1) = (%d, %d)\n", rect->x1, rect->y1);
769 SLOGI(" (x2, y2) = (%d, %d)\n", rect->x2, rect->y2);
770 SLOGI(" (width, height) = (%d, %d)\n", rect->x2 - rect->x1, rect->y2 - rect->y1);
771 } else {
772 SLOGI(" RECT_%s : NULL\n", title);
773 }
774 }
775
776 void printDataBlitRotate(int rotate)
777 {
778 SLOGI(" ROTATE : %d\n", rotate);
779 }
780
781 void printDataBlitScale(struct fimg2d_scale *scaling)
782 {
783 SLOGI(" SCALING\n");
784 if (scaling->mode != 0) {
785 SLOGI(" scale_mode : %s\n",
786 (scaling->mode == 1 ? "SCALING_BILINEAR" : "NO_SCALING"));
787 SLOGI(" src : (src_w, src_h) = (%d, %d)\n", scaling->src_w, scaling->src_h);
788 SLOGI(" dst : (dst_w, dst_h) = (%d, %d)\n", scaling->dst_w, scaling->dst_h);
789 SLOGI(" scaling_factor : (scale_w, scale_y) = (%3.2f, %3.2f)\n", (double)scaling->dst_w / scaling->src_w, (double)scaling->dst_h / scaling->src_h);
790 } else {
791 SLOGI(" scale_mode : NO_SCALING\n");
792 }
793 }