// File: /workspace/github_c_makefile_star2_O0/lukexi[P]eglstreams-mini/src/egl.c
// Function: SetupEGLDisplays
egl_display* SetupEGLDisplays(
    EGLDisplay eglDpy,
    EGLConfig eglConfig,
    EGLContext eglContext,
    kms_plane* Planes, int NumPlanes)
{

    EGLBoolean ret;

    egl_display* Displays = malloc(sizeof(egl_display) * NumPlanes);
    for (int PlaneIndex = 0; PlaneIndex < NumPlanes; PlaneIndex++) {
        kms_plane* Plane = &Planes[PlaneIndex];

        EGLAttrib layerAttribs[] = {
            EGL_DRM_PLANE_EXT,
            Plane->PlaneID,
            EGL_NONE,
        };
        printf("Setting up plane ID: %i\n", Plane->PlaneID);

        EGLAttrib streamAttribs[] = {
            EGL_STREAM_FIFO_LENGTH_KHR, 0,
            EGL_CONSUMER_AUTO_ACQUIRE_EXT, EGL_FALSE,
            EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0,
            EGL_NONE,
        };

        EGLint surfaceAttribs[] = {
            EGL_WIDTH,  Plane->Width,
            EGL_HEIGHT, Plane->Height,
            EGL_NONE
        };

        /* Find the EGLOutputLayer that corresponds to the DRM KMS plane. */
        EGLOutputLayerEXT eglLayer;
        EGLint n = 0;
        ret = pEglGetOutputLayersEXT(eglDpy, layerAttribs, &eglLayer, 1, &n);

        if (!ret || !n) {
            Fatal("Unable to get EGLOutputLayer for plane 0x%08x\n", Plane->PlaneID);
        }

        /* Set the OutputLayer's swap interval */
        pEglOutputLayerAttribEXT(eglDpy, eglLayer,
            EGL_SWAP_INTERVAL_EXT, 0);
        if (!ret) {
            Fatal("Unable to set EGLOutputLayer's swap interval\n");
        }

        /* Create an EGLStream. */
        EGLStreamKHR eglStream = pEglCreateStreamAttribNV(eglDpy, streamAttribs);

        if (eglStream == EGL_NO_STREAM_KHR) {
            EGLCheck("eglCreateStreamAttribNV");
            Fatal("Unable to create stream.\n");
        }

        /* Set the EGLOutputLayer as the consumer of the EGLStream. */

        ret = pEglStreamConsumerOutputEXT(eglDpy, eglStream, eglLayer);

        if (!ret) {
            Fatal("Unable to create EGLOutput stream consumer.\n");
        }

        /*
         * EGL_KHR_stream defines that normally stream consumers need to
         * explicitly retrieve frames from the stream.  That may be useful
         * when we attempt to better integrate
         * EGL_EXT_stream_consumer_egloutput with DRM atomic KMS requests.
         * But, EGL_EXT_stream_consumer_egloutput defines that by default:
         *
         *   On success, <layer> is bound to <stream>, <stream> is placed
         *   in the EGL_STREAM_STATE_CONNECTING_KHR state, and EGL_TRUE is
         *   returned.  Initially, no changes occur to the image displayed
         *   on <layer>. When the <stream> enters state
         *   EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR, <layer> will begin
         *   displaying frames, without further action required on the
         *   application's part, as they become available, taking into
         *   account any timestamps, swap intervals, or other limitations
         *   imposed by the stream or producer attributes.
         *
         * So, eglSwapBuffers() (to produce new frames) is sufficient for
         * the frames to be displayed.  That behavior can be altered with
         * the EGL_EXT_stream_acquire_mode extension.
         */

        /*
         * Create an EGLSurface as the producer of the EGLStream.  Once
         * the stream's producer and consumer are defined, the stream is
         * ready to use.  eglSwapBuffers() calls for the EGLSurface will
         * deliver to the stream's consumer, i.e., the DRM KMS plane
         * corresponding to the EGLOutputLayer.
         */

        EGLSurface eglSurface = pEglCreateStreamProducerSurfaceKHR(eglDpy, eglConfig,
                                                        eglStream, surfaceAttribs);
        if (eglSurface == EGL_NO_SURFACE) {
            Fatal("Unable to create EGLSurface stream producer.\n");
        }

        /*
         * Make current to the EGLSurface, so that OpenGL rendering is
         * directed to it.
         */
        Displays[PlaneIndex].EDID            = Plane->EDID;
        Displays[PlaneIndex].Width           = Plane->Width;
        Displays[PlaneIndex].Height          = Plane->Height;
        Displays[PlaneIndex].MonitorName     = strdup(Plane->EDID->MonitorName);
        Displays[PlaneIndex].SerialNumber    = strdup(Plane->EDID->SerialNumber);
        Displays[PlaneIndex].DisplayDevice   = eglDpy;
        Displays[PlaneIndex].Surface         = eglSurface;
        Displays[PlaneIndex].Context         = eglContext;
        Displays[PlaneIndex].Config          = eglConfig;
        Displays[PlaneIndex].Stream          = eglStream;
        Displays[PlaneIndex].Layer           = eglLayer;
        Displays[PlaneIndex].PageFlipPending = false;
    }


    return Displays;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movslq -0x24(%rbp), %rax
imulq $0x58, %rax, %rdi
callq 0x2120
movq %rax, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x3a74
movq -0x20(%rbp), %rax
movslq -0x34(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq $0x3235, -0x60(%rbp)    # imm = 0x3235
movq -0x40(%rbp), %rax
movl (%rax), %eax
movq %rax, -0x58(%rbp)
movq $0x3038, -0x50(%rbp)    # imm = 0x3038
movq -0x40(%rbp), %rax
movl (%rax), %esi
leaq 0x2eca(%rip), %rdi      # 0x6647
movb $0x0, %al
callq 0x2050
leaq -0xa0(%rbp), %rdi
xorl %esi, %esi
movl $0x38, %edx
callq 0x2080
movq $0x31fc, -0xa0(%rbp) # imm = 0x31FC
movq $0x332b, -0x90(%rbp) # imm = 0x332B
movq $0x321e, -0x80(%rbp)    # imm = 0x321E
movq $0x3038, -0x70(%rbp)    # imm = 0x3038
movl $0x3057, -0xc0(%rbp)    # imm = 0x3057
movq -0x40(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0xbc(%rbp)
movl $0x3056, -0xb8(%rbp)    # imm = 0x3056
movq -0x40(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0xb4(%rbp)
movl $0x3038, -0xb0(%rbp)    # imm = 0x3038
movl $0x0, -0xcc(%rbp)
movq 0x5a3a(%rip), %rax      # 0x9240
movq -0x8(%rbp), %rdi
leaq -0x60(%rbp), %rsi
leaq -0xc8(%rbp), %rdx
movl $0x1, %ecx
leaq -0xcc(%rbp), %r8
callq *%rax
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
je 0x3835
cmpl $0x0, -0xcc(%rbp)
jne 0x3849
movq -0x40(%rbp), %rax
movl (%rax), %esi
leaq 0x2e1e(%rip), %rdi      # 0x6660
movb $0x0, %al
callq 0x4cf0
movq 0x5a30(%rip), %rax      # 0x9280
movq -0x8(%rbp), %rdi
movq -0xc8(%rbp), %rsi
movl $0x322f, %edx           # imm = 0x322F
xorl %ecx, %ecx
callq *%rax
cmpl $0x0, -0x28(%rbp)
jne 0x3878
leaq 0x2e1e(%rip), %rdi      # 0x668f
movb $0x0, %al
callq 0x4cf0
movq 0x59f9(%rip), %rax      # 0x9278
movq -0x8(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq *%rax
movq %rax, -0xd8(%rbp)
cmpq $0x0, -0xd8(%rbp)
jne 0x38b7
leaq 0x296a(%rip), %rdi      # 0x620e
callq 0x34f0
leaq 0x2e0d(%rip), %rdi      # 0x66bd
movb $0x0, %al
callq 0x4cf0
movq 0x5992(%rip), %rax      # 0x9250
movq -0x8(%rbp), %rdi
movq -0xd8(%rbp), %rsi
movq -0xc8(%rbp), %rdx
callq *%rax
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
jne 0x38e9
leaq 0x2df5(%rip), %rdi      # 0x66d7
movb $0x0, %al
callq 0x4cf0
movq 0x5968(%rip), %rax      # 0x9258
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0xd8(%rbp), %rdx
leaq -0xc0(%rbp), %rcx
callq *%rax
movq %rax, -0xe0(%rbp)
cmpq $0x0, -0xe0(%rbp)
jne 0x3927
leaq 0x2de4(%rip), %rdi      # 0x6704
movb $0x0, %al
callq 0x4cf0
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x58, %rdx, %rdx
addq %rdx, %rax
movq %rcx, (%rax)
movq -0x40(%rbp), %rax
movl 0x4(%rax), %ecx
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x58, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x8(%rax)
movq -0x40(%rbp), %rax
movl 0x8(%rax), %ecx
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x58, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0xc(%rax)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rdi
callq 0x22e0
movq %rax, %rcx
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x58, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x10(%rax)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rdi
callq 0x22e0
movq %rax, %rcx
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x58, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x18(%rax)
movq -0x8(%rbp), %rcx
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x58, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x30(%rax)
movq -0xe0(%rbp), %rcx
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x58, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x20(%rax)
movq -0x18(%rbp), %rcx
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x58, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x28(%rax)
movq -0x10(%rbp), %rcx
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x58, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x38(%rax)
movq -0xd8(%rbp), %rcx
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x58, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x40(%rax)
movq -0xc8(%rbp), %rcx
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x58, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x48(%rax)
movq -0x30(%rbp), %rax
movslq -0x34(%rbp), %rcx
imulq $0x58, %rcx, %rcx
addq %rcx, %rax
movb $0x0, 0x50(%rax)
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x3737
movq -0x30(%rbp), %rax
addq $0xe0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)