// File: /workspace/github_cpp_makefile_star2_O3/Lut99[P]RayTracer/src/lib/Renderer.cpp
// Function: RayTracer::Renderer::render(RayTracer::RenderWorld*, RayTracer::Camera*)
Image Renderer::render(RenderWorld* world, Camera* cam) {
    Image out(cam->width, cam->height);
    ProgressBar prgrs(0, cam->width * cam->height - 1);

    // Render it (how depends on if the program is threaded or not)
    #ifndef THREADED

    for (int y = cam->height-1; y >= 0; y--) {
        for (int x = 0; x < cam->width; x++) {
            // Render the pixel
            out[y][x] = world->render_pixel(x, y, *cam);

            if (this->show_progressbar) {
                prgrs.update();
            }
        }
    }

    #else

    // Create a thread pool
    ThreadPool pool(this->n_threads, this->batch_size);

    // Use the thread pool to render it
    unsigned long batch_index = 0;
    unsigned long to_do = cam->width * cam->height;
    while (batch_index < to_do) {
        // Update the progressbar in any case for smoothness
        if (this->show_progressbar) {
            prgrs.set(batch_index);
        }

        // If a the queue is full, wait for another thread to notify us it has taken an element
        if (pool.batch_queue_full()) {
            pool.wait();
        }

        // Create a new batch and append it
        PixelBatch batch = pool.get_batch(cam->width, cam->height, batch_index);
        batch.camera = cam;
        batch.world = world;
        batch.out = &out;
        pool.add_batch(batch);
    }

    // Wait until all threads have been reaped
    pool.complete();
    pool.stop();

    // Update the bar one last time
    if (this->show_progressbar) {
        prgrs.set(batch_index);
    }

    #endif

    return out;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %r12
movl 0x8(%rcx), %esi
movl 0xc(%rcx), %edx
movq %rdi, (%rsp)
callq 0x63920
movslq 0x8(%r14), %rax
movslq 0xc(%r14), %rdx
imulq %rax, %rdx
decq %rdx
leaq 0x28(%rsp), %rdi
xorl %esi, %esi
callq 0x787e4
movl 0xc(%r14), %ebp
testl %ebp, %ebp
jle 0x618da
movl 0x8(%r14), %eax
leaq 0xa8(%rsp), %r13
movl %ebp, %edx
movq %rdx, 0x8(%rsp)
leal -0x1(%rdx), %ebp
testl %eax, %eax
jle 0x618d3
xorl %ebx, %ebx
movq %r13, %rdi
movq %r15, %rsi
movl %ebx, %edx
movl %ebp, %ecx
movq %r14, %r8
callq 0x7a78c
movq (%rsp), %rdi
movl %ebp, %esi
callq 0x63efc
movq %rax, 0x18(%rsp)
movl %edx, 0x20(%rsp)
leaq 0x18(%rsp), %rdi
movl %ebx, %esi
callq 0x6373e
movq %rax, 0x10(%rsp)
leaq 0x10(%rsp), %rdi
movq %r13, %rsi
callq 0x63712
cmpb $0x1, 0x8(%r12)
jne 0x618c9
movl $0x1, %esi
leaq 0x28(%rsp), %rdi
callq 0x78f2e
incl %ebx
movl 0x8(%r14), %eax
cmpl %eax, %ebx
jl 0x6186e
cmpl $0x2, 0x8(%rsp)
jge 0x6185e
leaq 0x78(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x618f5
movq 0x78(%rsp), %rsi
incq %rsi
callq 0x3a480
leaq 0x58(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x61910
movq 0x58(%rsp), %rsi
incq %rsi
callq 0x3a480
movq (%rsp), %rax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x6193c
jmp 0x6192f
jmp 0x6192f
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x62068
movq (%rsp), %rdi
callq 0x639f4
movq %rbx, %rdi
callq 0x3a790
nop