#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <pixman.h>
#include "recovery_gui_general.h"
#include "recovery_png.h"
#define MAX_PATH 256
#define MAX_FILE_PATH 512
+#if !defined(ROTATE)
+#define ROTATE 0
+#endif
+
#if !defined(RESDIR)
#define RESDIR "/usr/share/res"
#endif
const int y_offset_main_bg_text_pos = 300;
const int x_offset_prog_bar_img_pos = 240;
const int y_offset_prog_bar_img_pos = 355;
+int rotate_step = 0;
+int rollback_step = 0;
+int img_buf_width = 0;
+int img_buf_height = 0;
FbInfo s_fbi;
tdm_if_disp s_disp;
/*-----------------------------------------------------------------------------
_gr_direct_fill_rect
----------------------------------------------------------------------------*/
-static void _gr_direct_fill_rect(FbInfo *fbi, s32 x, s32 y, s32 w, s32 h, u32 color)
+static void _gr_direct_fill_rect(tbm_surface_info_s *surface_info, s32 x, s32 y, s32 w, s32 h, u32 color)
{
unsigned int *fb_buf_int = NULL;
unsigned int *fb_buf_cur = NULL;
s32 dy = 0;
s32 wb = 0;
- if (NULL == fbi)
+ if (NULL == surface_info)
return;
dx = w;
dy = h;
wb = w * sizeof(u32);
- fb_buf_int = (unsigned int *)fbi->buf[FRONT_BUFFER];
- fb_buf_int += y * fbi->w + x;
+ fb_buf_int = (unsigned int *)surface_info->planes[0].ptr;
+ fb_buf_int += y * surface_info->width + x;
fb_buf_cur = fb_buf_int;
while (dx--)
*fb_buf_cur++ = color;
fb_buf_cur -= w;
- fb_buf_cur += fbi->w;
+ fb_buf_cur += surface_info->width;
dy--;
while (dy--) {
memcpy((void*)fb_buf_cur, (void*)fb_buf_int, wb);
- fb_buf_cur += fbi->w;
+ fb_buf_cur += surface_info->width;
}
}
}
}
+static void _gr_direct_clear_screen_init(tbm_surface_info_s *surface_info, u32 color)
+{
+ unsigned int *fb_buf_int = NULL;
+ unsigned int *fb_buf_cur = NULL;
+ s32 dx = 0;
+ s32 dy = 0;
+ s32 w = 0;
+
+ if (NULL == surface_info)
+ return;
+
+ dx = surface_info->width;
+ dy = surface_info->height;
+ w = surface_info->width * sizeof(u32);
+
+ fb_buf_int = (unsigned int *)surface_info->planes[0].ptr;
+ fb_buf_cur = fb_buf_int;
+
+ while (dx--)
+ *fb_buf_cur++ = color;
+
+ dy--;
+ while (dy--) {
+ memcpy((void*)fb_buf_cur, (void*)fb_buf_int, w);
+ fb_buf_cur += surface_info->width;
+ }
+}
+
/*-----------------------------------------------------------------------------
_gr_direct_draw_text
----------------------------------------------------------------------------*/
-static void _gr_direct_draw_text(FbInfo *fbi, int percent)
+static void _gr_direct_draw_text(tbm_surface_info_s *surface_info, int percent)
{
char img_name[MAX_PATH];
int img_x;
if (read_png_file(img_name) < 0)
return;
- draw_png_img_xy(fbi, img_x, img_y);
+ //draw_png_img_xy(fbi, img_x, img_y);
+ draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
release_png_res();
}
if (read_png_file(img_name) < 0)
return;
- draw_png_img_xy(fbi, img_x, img_y);
+ //draw_png_img_xy(fbi, img_x, img_y);
+ draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
release_png_res();
}
if (read_png_file(img_name) < 0)
return;
- draw_png_img_xy(fbi, img_x, img_y);
+ //draw_png_img_xy(fbi, img_x, img_y);
+ draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
release_png_res();
img_x += 13;
if (read_png_file(img_name) < 0)
return;
- draw_png_img_xy(fbi, img_x, img_y);
+ //draw_png_img_xy(fbi, img_x, img_y);
+ draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
release_png_res();
}
/*-----------------------------------------------------------------------------
_gr_direct_draw_prog_text
----------------------------------------------------------------------------*/
-static void _gr_direct_draw_prog_text(FbInfo *fbi, int percent)
+static void _gr_direct_draw_prog_text(tbm_surface_info_s *surface_info, int percent)
{
if (percent <= 0)
percent = 0;
if (percent > 100)
percent = 100;
- _gr_direct_fill_rect(fbi, 610, 395, 65, 41, COLOR_BLACK);
- _gr_direct_draw_text(fbi, percent);
+ _gr_direct_fill_rect(surface_info, 610, 395, 65, 41, COLOR_BLACK);
+ _gr_direct_draw_text(surface_info, percent);
}
-static void _gr_direct_draw_main_prog_img(FbInfo *fbi, int percent)
+static void _gr_direct_draw_main_prog_img(tbm_surface_info_s *surface_info, int percent)
{
int img_x = 0;
int img_y = 0;
img_x = x_offset_prog_bar_img_pos;
img_y = y_offset_prog_bar_img_pos;
- draw_png_img_xy(fbi, img_x, img_y);
+ //draw_png_img_xy(fbi, img_x, img_y);
+ draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
release_png_res();
}
/*-----------------------------------------------------------------------------
_gr_direct_draw_main_img
----------------------------------------------------------------------------*/
-static void _gr_direct_draw_main_img(FbInfo *fbi)
+static void _gr_direct_draw_main_img(tbm_surface_info_s *surface_info)
{
int img_x = 0;
int img_y = 0;
img_x = 0;
img_y = 0;
- draw_png_img_xy(fbi, img_x, img_y);
+ //draw_png_img_xy(fbi, img_x, img_y);
+ draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
release_png_res();
if (read_png_file(IMG_BASE MAIN_TEXT_NAME) < 0)
img_x = x_offset_main_bg_text_pos;
img_y = y_offset_main_bg_text_pos;
- draw_png_img_xy(fbi, img_x, img_y);
+ //draw_png_img_xy(fbi, img_x, img_y);
+ draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
release_png_res();
}
+void _copy_buffers_by_rotate(void *srcptr, int srcw, int srch, int srcstride,
+ void *dstptr, int dstw, int dsth, int dststride,
+ int sx, int sy, int sw, int sh,
+ int dx, int dy, int dw, int dh, int rstep)
+{
+ pixman_image_t *src_img = NULL, *dst_img = NULL;
+ pixman_op_t op;
+
+ int buf_width;
+
+ buf_width = srcstride/4;
+ src_img = pixman_image_create_bits(PIXMAN_a8r8g8b8, buf_width, srch, (uint32_t*)srcptr, srcstride);
+ if(!src_img)
+ {
+ LOG("No source image.\n");
+ return;
+ }
+
+ buf_width = dststride/4;
+ dst_img = pixman_image_create_bits(PIXMAN_a8r8g8b8, buf_width, dsth, (uint32_t*)dstptr, dststride);
+
+ struct pixman_f_transform ft;
+ double scale_x, scale_y;
+ pixman_transform_t t;
+ pixman_f_transform_init_identity(&ft);
+
+ if (rstep > 0) {
+ int c = 0, s = 0, tx = 0, ty = 0;
+ switch (rstep) {
+ case 1:
+ c = 0, s = -1, tx = -dw;
+ break;
+ case 2:
+ c = -1, s = 0, tx = -dw, ty = -dh;
+ break;
+ case 3:
+ c = 0, s = 1, ty = -dh;
+ break;
+ }
+ pixman_f_transform_translate(&ft, NULL, tx, ty);
+ pixman_f_transform_rotate(&ft, NULL, c, s);
+ }
+
+ if (rstep % 2 == 0) {
+ scale_x = (double)sw / dw;
+ scale_y = (double)sh / dh;
+ } else {
+ scale_x = (double)sw / dh;
+ scale_y = (double)sh / dw;
+ }
+ pixman_f_transform_scale(&ft, NULL, scale_x, scale_y);
+ pixman_f_transform_translate(&ft, NULL, sx, sy);
+ pixman_transform_from_pixman_f_transform(&t, &ft);
+ pixman_image_set_transform(src_img, &t);
+
+
+ op = PIXMAN_OP_SRC;
+ pixman_image_composite(op, src_img, NULL, dst_img, 0, 0, 0, 0, dx, dy, dw, dh);
+
+ if (src_img)
+ pixman_image_unref(src_img);
+ if (dst_img)
+ pixman_image_unref(dst_img);
+}
+
/*-----------------------------------------------------------------------------
__init_screen
----------------------------------------------------------------------------*/
static void __init_screen(FbInfo *fbi)
{
- _gr_direct_clear_screen(fbi, COLOR_BLACK);
+ /* create tbm_surface for original image */
+ tbm_surface_h tbm_surface_ori = NULL;
+ tbm_surface_info_s surface_info_ori;
+ tbm_surface_ori = tbm_surface_create(img_buf_width, img_buf_height, TBM_FORMAT_ARGB8888); // rotated width, height
+ if(!tbm_surface_ori){
+ LOG("failed to tbm_surface_create\n");
+ }
+ tbm_surface_map(tbm_surface_ori, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &surface_info_ori);
+
+
+ _gr_direct_clear_screen_init(&surface_info_ori, COLOR_BLACK);
+
+ _gr_direct_draw_main_img(&surface_info_ori);
- //_gr_direct_draw_text_img(fbi);
+ _gr_direct_draw_main_prog_img(&surface_info_ori, 0);
- _gr_direct_draw_main_img(fbi);
+ _gr_direct_draw_prog_text(&surface_info_ori, 0);
- _gr_direct_draw_main_prog_img(fbi, 0);
- _gr_direct_draw_prog_text(fbi, 0);
+ _copy_buffers_by_rotate(surface_info_ori.planes[0].ptr, surface_info_ori.width, surface_info_ori.height, surface_info_ori.planes[0].stride,
+ fbi->buf[0], fbi->w, fbi->h, fbi->w * RGB32_PITCH,
+ 0,0,surface_info_ori.width, surface_info_ori.height,
+ 0,0,fbi->w, fbi->h, rotate_step);
+ tbm_surface_unmap(tbm_surface_ori);
+ tbm_surface_destroy(tbm_surface_ori);
}
-static void _gr_direct_progress_bar(FbInfo *fbi, int progress)
+static void _gr_direct_progress_bar(tbm_surface_info_s *surface_info, int progress)
{
char img_name[MAX_PATH];
static int prog_pre = 0;
int count = 0;
int prog_cnt = 0;
+ int img_x = 0;
+ int img_y = 0;
if (progress <= 0)
return;
prog_cnt = progress;
+
+ img_x = x_offset_prog_bar_img_pos;
+ img_y = y_offset_prog_bar_img_pos;
+
for (; prog_pre <= prog_cnt; prog_pre++) {
LOG("prog_pre/prog_cnt : %d, %d \n", prog_pre , prog_cnt);
return;
}
- draw_png_img_xy(fbi, 240, 355);
+ //draw_png_img_xy(fbi, 240, 355);
+ draw_png_img_original(surface_info->planes[0].ptr, img_x, img_y, surface_info->width, surface_info->height, surface_info->planes[0].stride);
release_png_res();
s_saved_percent = prog_pre;
- count++;
-
- if (count > 3)
- break;
+ if(progress != 100)
+ {
+ count++;
+ if (count > 3)
+ break;
+ }
}
}
LOG("recovery_gr_direct_progress progress : %d \n", s_percent_to_draw);
if (s_percent_to_draw > 0) {
- _gr_direct_progress_bar(&s_fbi, s_percent_to_draw);
- _gr_direct_draw_prog_text(&s_fbi, s_saved_percent);
+ /* create tbm_surface for original image */
+ tbm_surface_h tbm_surface_ori = NULL;
+ tbm_surface_info_s surface_info_ori;
+
+ tbm_surface_ori = tbm_surface_create(img_buf_width, img_buf_height, TBM_FORMAT_ARGB8888); // rotated width, height
+ if(!tbm_surface_ori){
+ LOG("failed to tbm_surface_create\n");
+ }
+ tbm_surface_map(tbm_surface_ori, TBM_SURF_OPTION_READ | TBM_SURF_OPTION_WRITE, &surface_info_ori);
+ // need to keep previous image
+ _copy_buffers_by_rotate(s_fbi.buf[0], s_fbi.w, s_fbi.h, s_fbi.w * RGB32_PITCH,
+ surface_info_ori.planes[0].ptr, surface_info_ori.width, surface_info_ori.height, surface_info_ori.planes[0].stride,
+ 0,0,s_fbi.w, s_fbi.h,
+ 0,0,surface_info_ori.width, surface_info_ori.height, rollback_step);
+
+ _gr_direct_progress_bar(&surface_info_ori, s_percent_to_draw);
+ _gr_direct_draw_prog_text(&surface_info_ori, s_saved_percent);
+
+ _copy_buffers_by_rotate(surface_info_ori.planes[0].ptr, surface_info_ori.width, surface_info_ori.height, surface_info_ori.planes[0].stride,
+ s_fbi.buf[0], s_fbi.w, s_fbi.h, s_fbi.w * RGB32_PITCH,
+ 0,0,surface_info_ori.width, surface_info_ori.height,
+ 0,0,s_fbi.w, s_fbi.h, rotate_step);
+ tbm_surface_unmap(tbm_surface_ori);
+ tbm_surface_destroy(tbm_surface_ori);
} else if (s_percent_to_draw == 0) {
s_saved_percent = 0;
}
+
_gr_direct_update_screen();
}
_gr_direct_update_screen();
}
+void _get_rotate(void)
+{
+ char *rotate_state = getenv("ROTATE_STATE");
+ int rotate_angle = -1;
+ if(!rotate_state)
+ {
+ rotate_angle = ROTATE;
+ }
+ else
+ {
+ rotate_angle = atoi(rotate_state);
+ }
+
+ LOG("Print Rotate Angle value = %d\n", rotate_angle);
+
+ rotate_step = (rotate_angle + 360) / 90 % 4;
+ rollback_step = (4 - rotate_step) % 4;
+ LOG("rotate_step = %d, rollback_step = %d\n", rotate_step, rollback_step);
+
+ if (rotate_step % 2 == 0) {
+ img_buf_width = s_fbi.w;
+ img_buf_height = s_fbi.h;
+ } else {
+ img_buf_width = s_fbi.h;
+ img_buf_height = s_fbi.w;
+ }
+ LOG("Print Img buffer(=image w,h) width = %d, height = %d\n", img_buf_width, img_buf_height);
+}
+
/*-----------------------------------------------------------------------------
recovery_gr_direct_init
----------------------------------------------------------------------------*/
if (fb_open(&s_fbi) < 0)
LOG("fb_open failed \n");
+ _get_rotate();
__init_screen(&s_fbi);
tdm_if_lcd_on(&s_disp);
}
+/*-----------------------------------------------------------------------------
+ draw_png_img_original()
+ ----------------------------------------------------------------------------*/
+void draw_png_img_original(void *fbi, int x1, int y1, int fbi_w, int fbi_h, int fbi_stride)
+{
+ unsigned int *fb_buf_cur = NULL;
+ int bpp;
+ int x, y;
+ int end_width, end_height;
+ /* temp patch - lcd resoultion for qualcomm */
+
+ fb_buf_cur = (unsigned int *)fbi;
+
+ /* check out range */
+ if ((x1 > fbi_w ) || (y1 > fbi_h)) {
+ LOG("[draw_png_img_xy] output range exceeds frame buffer range \n");
+ return;
+ }
+ if(x1 + png_img_width > fbi_w)
+ end_width = fbi_w- x1;
+ else
+ end_width = png_img_width;
+ if(y1 + png_img_height > fbi_h)
+ end_height = fbi_h - y1;
+ else
+ end_height = png_img_height;
+
+ LOG("png_color_type = [%d]", png_color_type);
+ if (png_color_type == PNG_COLOR_TYPE_RGB) {
+ bpp = 3;
+ LOG("png color type is PNG_COLOR_TYPE_RGB, png_color_type = [%d]\n", png_color_type);
+ } else if (png_color_type == PNG_COLOR_TYPE_RGBA) {
+ bpp = 4;
+ LOG("png color type is PNG_COLOR_TYPE_RGBA, png_color_type = [%d]\n", png_color_type);
+ } else {
+ LOG("[draw_png_img_xy] png type does not match RGB or RGBA \n");
+
+ LOG("[draw_png_img_xy] png type does not match RGB or RGBA, png_color_type = [%d] \n", png_color_type);
+ return;
+ }
+
+ /* temp patch - lcd resoultion for qualcomm */
+ for (y = 0; y < png_img_height; y++) {
+ if(y > end_height) continue;
+ fb_buf_cur = (unsigned int *) (fbi + ((y1 + y) * fbi_stride));
+ fb_buf_cur += x1;
+ png_byte *row = (png_byte *) row_pointers[y];
+ for (x = 0; x < png_img_width; x++) {
+ if(x > end_width) continue;
+ if (bpp == 3) {
+ if (png_bit_depth == 8) {
+ (*fb_buf_cur) = ((*fb_buf_cur)&0xff000000) |
+ (row[0] << 16) | (row[1] << 8) | (row[2]);
+ row += bpp;
+ } else if (png_bit_depth == 16) {
+ (*fb_buf_cur) = ((*fb_buf_cur)&0xff000000) |
+ (row[0] << 16) | (row[2] << 8) | (row[4]);
+ row += bpp*2;
+ }
+ } else if (bpp == 4) {
+ if (png_bit_depth == 8) {
+ if (row[3] != 0) {
+ char r1, g1, b1, a1;
+ char r2, g2, b2, a2;
+ char r3, g3, b3, a3;
+ // background pixel
+ b1 = ((*fb_buf_cur)&0x000000ff);
+ g1 = ((*fb_buf_cur)&0x0000ff00)>>8;
+ r1 = ((*fb_buf_cur)&0x00ff0000)>>16;
+ a1 = ((*fb_buf_cur)&0xff000000)>>24;
+ // new pixel
+ r2 = row[0];
+ g2 = row[1];
+ b2 = row[2];
+ a2 = row[3];
+ // blended pixel
+ r3 = (r2 * a2 + r1 * (0xff - a2)) >> 8 ;
+ g3 = (g2 * a2 + g1 * (0xff - a2)) >> 8;
+ b3 = (b2 * a2 + b1 * (0xff - a2)) >> 8;
+ a3 = a1;
+ (*fb_buf_cur) = (a3 << 24) |
+ (r3 << 16) | (g3 << 8) | (b3);
+ }
+ row += bpp;
+ } else if (png_bit_depth == 16) {
+ if (row[6] != 0) {
+ short r1, g1, b1, a1;
+ short r2, g2, b2, a2;
+ char r3, g3, b3, a3;
+ // background pixel
+ b1 = ((*fb_buf_cur)&0x000000ff)<<8;
+ g1 = ((*fb_buf_cur)&0x0000ff00);
+ r1 = ((*fb_buf_cur)&0x00ff0000)>>8;
+ a1 = ((*fb_buf_cur)&0xff000000)>>16;
+ // new pixel
+ r2 = (row[0]<<8) + row[1];
+ g2 = (row[2]<<8) + row[3];
+ b2 = (row[4]<<8) + row[5];
+ a2 = (row[6]<<8) + row[7];
+ // blended pixel
+ r3 = (r2 * a2 + r1 * (0xffff - a2)) >> 24;
+ g3 = (g2 * a2 + g1 * (0xffff - a2)) >> 24;
+ b3 = (b2 * a2 + b1 * (0xffff - a2)) >> 24;
+ a3 = a1 >> 8;
+ (*fb_buf_cur) = (a3 << 24) |
+ (r3 << 16) | (g3 << 8) | (b3);
+ }
+ row += bpp*2;
+ }
+ }
+ fb_buf_cur++;
+ }
+ }
+
+}
+
+
/*-----------------------------------------------------------------------------
draw_png_mask_xy()
- draw pixel only when alpha>0 of given png image