// File: /workspace/github_c_makefile_star2_O2/OnionIoT[P]lv_example/lv_drivers/display/fbdev.c
// Function: fbdev_flush
void fbdev_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
{
    if(fbp == NULL ||
            area->x2 < 0 ||
            area->y2 < 0 ||
            area->x1 > (int32_t)vinfo.xres - 1 ||
            area->y1 > (int32_t)vinfo.yres - 1) {
        lv_disp_flush_ready(drv);
        return;
    }

    /*Truncate the area to the screen*/
    int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
    int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
    int32_t act_x2 = area->x2 > (int32_t)vinfo.xres - 1 ? (int32_t)vinfo.xres - 1 : area->x2;
    int32_t act_y2 = area->y2 > (int32_t)vinfo.yres - 1 ? (int32_t)vinfo.yres - 1 : area->y2;


    lv_coord_t w = lv_area_get_width(area);
    long int location = 0;
    long int byte_location = 0;
    unsigned char bit_location = 0;

    /*32 or 24 bit per pixel*/
    if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
        uint32_t * fbp32 = (uint32_t *)fbp;
        int32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length / 4;
            memcpy(&fbp32[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1) * 4);
            color_p += w;
        }
    }
    /*16 bit per pixel*/
    else if(vinfo.bits_per_pixel == 16) {
        uint16_t * fbp16 = (uint16_t *)fbp;
        int32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length / 2;
            memcpy(&fbp16[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1) * 2);
            color_p += w;
        }
    }
    /*8 bit per pixel*/
    else if(vinfo.bits_per_pixel == 8) {
        uint8_t * fbp8 = (uint8_t *)fbp;
        int32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            location = (act_x1 + vinfo.xoffset) + (y + vinfo.yoffset) * finfo.line_length;
            memcpy(&fbp8[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1));
            color_p += w;
        }
    }
    /*1 bit per pixel*/
    else if(vinfo.bits_per_pixel == 1) {
        uint8_t * fbp8 = (uint8_t *)fbp;
        int32_t x;
        int32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            for(x = act_x1; x <= act_x2; x++) {
                location = (x + vinfo.xoffset) + (y + vinfo.yoffset) * vinfo.xres;
                byte_location = location / 8; /* find the byte we need to change */
                bit_location = location % 8; /* inside the byte found, find the bit we need to change */
                fbp8[byte_location] &= ~(((uint8_t)(1)) << bit_location);
                fbp8[byte_location] |= ((uint8_t)(color_p->full)) << bit_location;
                color_p++;
            }

            color_p += area->x2 - act_x2;
        }
    } else {
        /*Not supported bit per pixel*/
    }

    //May be some direct update command is required
    //ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));

    lv_disp_flush_ready(drv);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, 0x10(%rsp)
movq 0x35133(%rip), %r12     # 0x6fbf8
testq %r12, %r12
je 0x3acdb
movswl 0x4(%rsi), %ecx
testl %ecx, %ecx
js 0x3acdb
movq %rdx, %rbx
movswl 0x6(%rsi), %edx
testl %edx, %edx
js 0x3acdb
movswl (%rsi), %edi
movl 0x3505d(%rip), %r8d     # 0x6fb50
cmpl %edi, %r8d
jle 0x3acdb
movswl 0x2(%rsi), %ebp
movl 0x3504d(%rip), %r9d     # 0x6fb54
cmpl %ebp, %r9d
jle 0x3acdb
xorl %eax, %eax
testw %di, %di
movl $0x0, %r13d
cmovgl %edi, %r13d
movl $0xffff, %r10d          # imm = 0xFFFF
andl %r10d, %r13d
testw %bp, %bp
cmovlel %eax, %ebp
andl %r10d, %ebp
leal -0x1(%r8), %eax
cmpl %ecx, %r8d
cmovgl %ecx, %eax
leal -0x1(%r9), %r8d
cmpl %edx, %r9d
cmovgl %edx, %r8d
movl %r8d, 0xc(%rsp)
subl %edi, %ecx
incl %ecx
movl 0x35013(%rip), %edx     # 0x6fb68
cmpl $0x20, %edx
je 0x3abfa
cmpl $0x8, %edx
je 0x3ac4b
cmpl $0x10, %edx
je 0x3ac8f
cmpl $0x18, %edx
je 0x3abfa
cmpl $0x1, %edx
jne 0x3acdb
movslq %eax, %rdx
addq %rdx, %rdx
negq %rdx
pushq $0x1
popq %rdi
cmpl 0xc(%rsp), %ebp
jg 0x3acdb
movl %r13d, %r8d
cmpl %eax, %r8d
jg 0x3abea
movl 0x34fbe(%rip), %ecx     # 0x6fb64
addl %ebp, %ecx
imull 0x34fa1(%rip), %ecx     # 0x6fb50
addl 0x34fab(%rip), %ecx     # 0x6fb60
addl %r8d, %ecx
movl %ecx, %r9d
shrl $0x3, %r9d
andb $0x7, %cl
movl %edi, %r10d
shll %cl, %r10d
notb %r10b
andb (%r12,%r9), %r10b
movb %r10b, (%r12,%r9)
movzwl (%rbx), %r11d
shll %cl, %r11d
orb %r10b, %r11b
movb %r11b, (%r12,%r9)
addq $0x2, %rbx
incl %r8d
jmp 0x3ab9b
movswq 0x4(%rsi), %rcx
addq %rdx, %rbx
leaq (%rbx,%rcx,2), %rbx
incl %ebp
jmp 0x3ab8e
subl %r13d, %eax
leal 0x4(,%rax,4), %eax
movslq %eax, %r15
movswq %cx, %r14
addq %r14, %r14
cmpl 0xc(%rsp), %ebp
jg 0x3acdb
movl 0x34f42(%rip), %eax     # 0x6fb60
movl 0x34f40(%rip), %ecx     # 0x6fb64
addl %ebp, %ecx
imull 0x34f03(%rip), %ecx     # 0x6fb30
addl %r13d, %eax
shrl $0x2, %ecx
addl %eax, %ecx
leaq (%r12,%rcx,4), %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x20f0
incl %ebp
addq %r14, %rbx
jmp 0x3ac0e
subl %r13d, %eax
incl %eax
movslq %eax, %r15
movswq %cx, %r14
addq %r14, %r14
cmpl 0xc(%rsp), %ebp
jg 0x3acdb
movl 0x34efa(%rip), %eax     # 0x6fb60
addl %r13d, %eax
movl 0x34ef5(%rip), %edi     # 0x6fb64
addl %ebp, %edi
imull 0x34eb8(%rip), %edi     # 0x6fb30
addl %eax, %edi
addq %r12, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x20f0
incl %ebp
addq %r14, %rbx
jmp 0x3ac5a
subl %r13d, %eax
leal 0x2(,%rax,2), %eax
movslq %eax, %r14
movswq %cx, %r15
addq %r15, %r15
cmpl 0xc(%rsp), %ebp
jg 0x3acdb
movl 0x34eb1(%rip), %eax     # 0x6fb60
movl 0x34eaf(%rip), %ecx     # 0x6fb64
addl %ebp, %ecx
imull 0x34e72(%rip), %ecx     # 0x6fb30
addl %r13d, %eax
shrl %ecx
addl %eax, %ecx
leaq (%r12,%rcx,2), %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x20f0
incl %ebp
addq %r15, %rbx
jmp 0x3aca3
movq 0x10(%rsp), %rdi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x7e1c
nop