/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
  Atomic KMSDRM backend by Manuel Alfayate Corchete <redwindwanderer@gmail.com>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/

#include "../../SDL_internal.h"

#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL

#include "SDL_kmsdrmvideo.h"
#include "SDL_kmsdrmopengles.h"
#include "SDL_kmsdrmdyn.h"

#ifndef EGL_PLATFORM_GBM_MESA
#define EGL_PLATFORM_GBM_MESA 0x31D7
#endif

/* EGL implementation of SDL OpenGL support */

void
KMSDRM_GLES_DefaultProfileConfig(_THIS, int *mask, int *major, int *minor)
{
    /* if SDL was _also_ built with the Raspberry Pi driver (so we're
       definitely a Pi device), default to GLES2. */
#if SDL_VIDEO_DRIVER_RPI
    *mask = SDL_GL_CONTEXT_PROFILE_ES;
    *major = 2;
    *minor = 0;
#endif
}


int
KMSDRM_GLES_LoadLibrary(_THIS, const char *path) {
    NativeDisplayType display = (NativeDisplayType)((SDL_VideoData *)_this->driverdata)->gbm_dev;
    return SDL_EGL_LoadLibrary(_this, path, display, EGL_PLATFORM_GBM_MESA);
}

SDL_EGL_CreateContext_impl(KMSDRM)

int KMSDRM_GLES_SetSwapInterval(_THIS, int interval) {
    if (!_this->egl_data) {
        return SDL_SetError("EGL not initialized");
    }

    if (interval == 0 || interval == 1) {
        _this->egl_data->egl_swapinterval = interval;
    } else {
        return SDL_SetError("Only swap intervals of 0 or 1 are supported");
    }

    return 0;
}

/*********************************/
/* Atomic functions block        */
/*********************************/

#define VOID2U64(x) ((uint64_t)(unsigned long)(x))

static EGLSyncKHR create_fence(int fd, _THIS)
{
	EGLint attrib_list[] = {
		EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd,
		EGL_NONE,
	};
	EGLSyncKHR fence = _this->egl_data->eglCreateSyncKHR(_this->egl_data->egl_display,
			EGL_SYNC_NATIVE_FENCE_ANDROID, attrib_list);
	assert(fence);
	return fence;
}

int
KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window)
{
    SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata);
    SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
    KMSDRM_FBInfo *fb;
    KMSDRM_PlaneInfo info = {0};

    /* Get the EGL context, now that SDL_CreateRenderer() has already been called,
       and call eglMakeCurrent() on it and the EGL surface. */
#if SDL_VIDEO_OPENGL_EGL
    if (windata->egl_context_pending) {
        EGLContext egl_context;
        egl_context = (EGLContext)SDL_GL_GetCurrentContext();
        SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context);
        windata->egl_context_pending = SDL_FALSE;
    }   
#endif

    /*************************************************************************/
    /* Block for telling KMS to wait for GPU rendering of the current frame  */
    /* before applying the KMS changes requested in the atomic ioctl.        */
    /*************************************************************************/

    /* Create the fence that will be inserted in the cmdstream exactly at the end
       of the gl commands that form a frame. KMS will have to wait on it before doing a pageflip. */
    dispdata->gpu_fence = create_fence(EGL_NO_NATIVE_FENCE_FD_ANDROID, _this);
    assert(dispdata->gpu_fence);

    /* Mark, at EGL level, the buffer that we want to become the new front buffer.
       However, it won't really happen until we request a pageflip at the KMS level and it completes. */
    if (! _this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, windata->egl_surface)) {
        return SDL_EGL_SetError("Failed to swap EGL buffers", "eglSwapBuffers");
    }

    /* It's safe to get the gpu_fence FD now, because eglSwapBuffers flushes it down the cmdstream, 
       so it's now in place in the cmdstream.
       Atomic ioctl will pass the in-fence fd into the kernel, telling KMS that it has to wait for GPU to
       finish rendering the frame before doing the changes requested in the atomic ioct (pageflip in this case). */
    dispdata->kms_in_fence_fd = _this->egl_data->eglDupNativeFenceFDANDROID(_this->egl_data->egl_display, dispdata->gpu_fence);
    _this->egl_data->eglDestroySyncKHR(_this->egl_data->egl_display, dispdata->gpu_fence);
    assert(dispdata->kms_in_fence_fd != -1);

    /***************/
    /* Block ends. */
    /***************/

    /* Lock the buffer that is marked by eglSwapBuffers() to become the next front buffer (so it can not
       be chosen by EGL as back buffer to draw on), and get a handle to it to request the pageflip on it.
       REMEMBER that gbm_surface_lock_front_buffer() ALWAYS has to be called after eglSwapBuffers(). */
    windata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(windata->gs);
    if (!windata->next_bo) {
	return SDL_SetError("Failed to lock frontbuffer");
    }
    fb = KMSDRM_FBFromBO(_this, windata->next_bo);
    if (!fb) {
	 return SDL_SetError("Failed to get a new framebuffer from BO");
    }

    /* Add the pageflip to the request list. */
    info.plane = dispdata->display_plane;
    info.crtc_id = dispdata->crtc->crtc->crtc_id;
    info.fb_id = fb->fb_id;

    info.src_w = windata->src_w;
    info.src_h = windata->src_h;
    info.crtc_w = windata->output_w;
    info.crtc_h = windata->output_h;
    info.crtc_x = windata->output_x;

    if (drm_atomic_set_plane_props(&info)) {
        return SDL_SetError("Failed to request prop changes for setting plane buffer and CRTC");
    }

    /* Set the IN_FENCE and OUT_FENCE props only here, since this is the only place
       on which we're interested in managing who and when should access the buffers
       that the display plane uses, and that's what these props are for. */
    if (dispdata->kms_in_fence_fd != -1)
    {
	if (add_crtc_property(dispdata->atomic_req, dispdata->crtc, "OUT_FENCE_PTR",
			          VOID2U64(&dispdata->kms_out_fence_fd)) < 0)
            return SDL_SetError("Failed to set CRTC OUT_FENCE_PTR prop");
	if (add_plane_property(dispdata->atomic_req, dispdata->display_plane, "IN_FENCE_FD", dispdata->kms_in_fence_fd) < 0)
            return SDL_SetError("Failed to set plane IN_FENCE_FD prop");
    }

    /* Issue the one and only atomic commit where all changes will be requested!.
       We need e a non-blocking atomic commit for triple buffering, because we 
       must not block on this atomic commit so we can re-enter program loop once more. */
    if (drm_atomic_commit(_this, SDL_FALSE)) {
        return SDL_SetError("Failed to issue atomic commit on pageflip");
    }

    /* Release the last front buffer so EGL can chose it as back buffer and render on it again. */
    if (windata->bo) {
	KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo);
    }

    /* Take note of current front buffer, so we can free it next time we come here. */
    windata->bo = windata->next_bo;

    /**************************************************************************/
    /* Block for telling GPU to wait for completion of requested KMS changes  */
    /* before starting cmdstream execution (=next frame rendering).           */
    /**************************************************************************/

    /* Import the kms fence from the out fence fd. We need it to tell GPU to wait for pageflip to complete. */
    dispdata->kms_fence = create_fence(dispdata->kms_out_fence_fd, _this);
    assert(dispdata->kms_fence);

    /* Reset out fence FD value because the fence is now away from us, on the driver side. */
    dispdata->kms_out_fence_fd = -1;

    /* Tell the GPU to wait until the requested pageflip has completed. */
    _this->egl_data->eglWaitSyncKHR(_this->egl_data->egl_display, dispdata->kms_fence, 0);

    /***************/
    /* Block ends. */
    /***************/

    return 0;
}

int
KMSDRM_GLES_SwapWindowDB(_THIS, SDL_Window * window)
{
    SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata);
    SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
    KMSDRM_FBInfo *fb;
    KMSDRM_PlaneInfo info = {0};

    /* Get the EGL context, now that SDL_CreateRenderer() has already been called,
       and call eglMakeCurrent() on it and the EGL surface. */
#if SDL_VIDEO_OPENGL_EGL
    if (windata->egl_context_pending) {
        EGLContext egl_context;
        egl_context = (EGLContext)SDL_GL_GetCurrentContext();
        SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context);
        windata->egl_context_pending = SDL_FALSE;
    }   
#endif

    /****************************************************************************************************/
    /* In double-buffer mode, atomic commit will always be synchronous/blocking (ie: won't return until */
    /* the requested changes are really done).                                                          */
    /* Also, there's no need to fence KMS or the GPU, because we won't be entering game loop again      */
    /* (hence not building or executing a new cmdstring) until pageflip is done.                        */
    /****************************************************************************************************/ 

    /* Mark, at EGL level, the buffer that we want to become the new front buffer.
       However, it won't really happen until we request a pageflip at the KMS level and it completes. */
    if (! _this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, windata->egl_surface)) {
        return SDL_EGL_SetError("Failed to swap EGL buffers", "eglSwapBuffers");
    }

    /* Lock the buffer that is marked by eglSwapBuffers() to become the next front buffer (so it can not
       be chosen by EGL as back buffer to draw on), and get a handle to it to request the pageflip on it. */
    windata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(windata->gs);
    if (!windata->next_bo) {
        return SDL_SetError("Failed to lock frontbuffer");
    }
    fb = KMSDRM_FBFromBO(_this, windata->next_bo);
    if (!fb) {
        return SDL_SetError("Failed to get a new framebuffer BO");
    }

    /* Add the pageflip to the request list. */
    info.plane = dispdata->display_plane;
    info.crtc_id = dispdata->crtc->crtc->crtc_id;
    info.fb_id = fb->fb_id;

    info.src_w = windata->src_w;
    info.src_h = windata->src_h;
    info.crtc_w = windata->output_w;
    info.crtc_h = windata->output_h;
    info.crtc_x = windata->output_x;

    if (drm_atomic_set_plane_props(&info)) {
        return SDL_SetError("Failed to request prop changes for setting plane buffer and CRTC");
    }

    /* Re-connect the connector to the CRTC, and activate the CRTC again.
       Just in case we come here after a DestroySurfaces() call. */
    if (add_connector_property(dispdata->atomic_req, dispdata->connector , "CRTC_ID",
            dispdata->crtc->crtc->crtc_id) < 0)
        return SDL_SetError("Failed to set CONNECTOR prop CRTC_ID to zero before buffer destruction");

    if (add_crtc_property(dispdata->atomic_req, dispdata->crtc , "ACTIVE", 1) < 0)
        return SDL_SetError("Failed to set CRTC prop ACTIVE to zero before buffer destruction");

    /* Issue the one and only atomic commit where all changes will be requested!. 
       Blocking for double buffering: won't return until completed. */
    if (drm_atomic_commit(_this, SDL_TRUE)) {
        return SDL_SetError("Failed to issue atomic commit");
    }

    /* Release last front buffer so EGL can chose it as back buffer and render on it again. */
    if (windata->bo) {
	KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo);
    }

    /* Take note of current front buffer, so we can free it next time we come here. */
    windata->bo = windata->next_bo;

    return 0;
}


/***************************************/
/* End of Atomic functions block       */
/***************************************/

SDL_EGL_MakeCurrent_impl(KMSDRM)

#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */

/* vi: set ts=4 sw=4 expandtab: */
