// File: /workspace/github_cpp_makefile_star2_O1/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 0x63e38
movslq 0x8(%r14), %rax
movslq 0xc(%r14), %rdx
imulq %rax, %rdx
decq %rdx
leaq 0x28(%rsp), %rdi
xorl %esi, %esi
callq 0x791c4
movl 0xc(%r14), %ebp
testl %ebp, %ebp
jle 0x61e23
leaq 0xa8(%rsp), %r13
movl %ebp, %ecx
movq %rcx, 0x8(%rsp)
leal -0x1(%rcx), %ebp
cmpl $0x0, 0x8(%r14)
jle 0x61e1c
xorl %ebx, %ebx
movq %r13, %rdi
movq %r15, %rsi
movl %ebx, %edx
movl %ebp, %ecx
movq %r14, %r8
callq 0x7b0ea
movq (%rsp), %rdi
movl %ebp, %esi
callq 0x643fa
movq %rax, 0x18(%rsp)
movl %edx, 0x20(%rsp)
leaq 0x18(%rsp), %rdi
movl %ebx, %esi
callq 0x63c6a
movq %rax, 0x10(%rsp)
leaq 0x10(%rsp), %rdi
movq %r13, %rsi
callq 0x63c3e
cmpb $0x1, 0x8(%r12)
jne 0x61e14
movl $0x1, %esi
leaq 0x28(%rsp), %rdi
callq 0x798f8
incl %ebx
cmpl 0x8(%r14), %ebx
jl 0x61db9
cmpl $0x2, 0x8(%rsp)
jge 0x61da6
leaq 0x78(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x61e3e
movq 0x78(%rsp), %rsi
incq %rsi
callq 0x3a470
leaq 0x58(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x61e59
movq 0x58(%rsp), %rsi
incq %rsi
callq 0x3a470
movq (%rsp), %rax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x61e85
jmp 0x61e78
jmp 0x61e78
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x625b4
movq (%rsp), %rdi
callq 0x63f0c
movq %rbx, %rdi
callq 0x3a780