/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>

  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_RENDER_VITA_GXM

#include "../SDL_sysrender.h"

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>

#include "SDL_render_vita_gxm_types.h"
#include "SDL_render_vita_gxm_tools.h"
#include "SDL_render_vita_gxm_memory.h"

#include <psp2/common_dialog.h>

/* #define DEBUG_RAZOR */

#ifdef DEBUG_RAZOR
#include <psp2/sysmodule.h>
#endif

static int VITA_GXM_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props);

static void VITA_GXM_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event);

static SDL_bool VITA_GXM_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode);

static int VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props);

static int VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
                                  const SDL_Rect *rect, const void *pixels, int pitch);

static int VITA_GXM_UpdateTextureYUV(SDL_Renderer *renderer, SDL_Texture *texture,
                                     const SDL_Rect *rect,
                                     const Uint8 *Yplane, int Ypitch,
                                     const Uint8 *Uplane, int Upitch,
                                     const Uint8 *Vplane, int Vpitch);

static int VITA_GXM_UpdateTextureNV(SDL_Renderer *renderer, SDL_Texture *texture,
                                    const SDL_Rect *rect,
                                    const Uint8 *Yplane, int Ypitch,
                                    const Uint8 *UVplane, int UVpitch);

static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
                                const SDL_Rect *rect, void **pixels, int *pitch);

static void VITA_GXM_UnlockTexture(SDL_Renderer *renderer,
                                   SDL_Texture *texture);

static void VITA_GXM_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode);

static int VITA_GXM_SetRenderTarget(SDL_Renderer *renderer,
                                    SDL_Texture *texture);

static int VITA_GXM_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd);

static int VITA_GXM_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd);

static int VITA_GXM_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count);
static int VITA_GXM_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count);

static int VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
                                  const float *xy, int xy_stride, const SDL_FColor *color, int color_stride, const float *uv, int uv_stride,
                                  int num_vertices, const void *indices, int num_indices, int size_indices,
                                  float scale_x, float scale_y);

static int VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd);

static void VITA_GXM_InvalidateCachedState(SDL_Renderer *renderer);

static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize);

static SDL_Surface *VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect);

static int VITA_GXM_RenderPresent(SDL_Renderer *renderer);
static void VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture);
static void VITA_GXM_DestroyRenderer(SDL_Renderer *renderer);

SDL_RenderDriver VITA_GXM_RenderDriver = {
    VITA_GXM_CreateRenderer, "VITA gxm"
};

static int PixelFormatToVITAFMT(Uint32 format)
{
    switch (format) {
    case SDL_PIXELFORMAT_ARGB8888:
        return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB;
    case SDL_PIXELFORMAT_XRGB8888:
        return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB;
    case SDL_PIXELFORMAT_XBGR8888:
        return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
    case SDL_PIXELFORMAT_ABGR8888:
        return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
    case SDL_PIXELFORMAT_RGB565:
        return SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB;
    case SDL_PIXELFORMAT_BGR565:
        return SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR;
    case SDL_PIXELFORMAT_YV12:
        return SCE_GXM_TEXTURE_FORMAT_YVU420P3_CSC0;
    case SDL_PIXELFORMAT_IYUV:
        return SCE_GXM_TEXTURE_FORMAT_YUV420P3_CSC0;
    // should be the other way around. looks like SCE bug.
    case SDL_PIXELFORMAT_NV12:
        return SCE_GXM_TEXTURE_FORMAT_YVU420P2_CSC0;
    case SDL_PIXELFORMAT_NV21:
        return SCE_GXM_TEXTURE_FORMAT_YUV420P2_CSC0;
    default:
        return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
    }
}

void StartDrawing(SDL_Renderer *renderer)
{
    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
    if (data->drawing) {
        return;
    }

    data->drawstate.texture = NULL;
    data->drawstate.vertex_program = NULL;
    data->drawstate.fragment_program = NULL;
    data->drawstate.last_command = -1;
    data->drawstate.viewport_dirty = SDL_TRUE;

    // reset blend mode
    //    data->currentBlendMode = SDL_BLENDMODE_BLEND;
    //    fragment_programs *in = &data->blendFragmentPrograms.blend_mode_blend;
    //    data->colorFragmentProgram = in->color;
    //    data->textureFragmentProgram = in->texture;

    if (!renderer->target) {
        sceGxmBeginScene(
            data->gxm_context,
            0,
            data->renderTarget,
            NULL,
            NULL,
            data->displayBufferSync[data->backBufferIndex],
            &data->displaySurface[data->backBufferIndex],
            &data->depthSurface);
    } else {
        VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)renderer->target->driverdata;

        sceGxmBeginScene(
            data->gxm_context,
            0,
            vita_texture->tex->gxm_rendertarget,
            NULL,
            NULL,
            NULL,
            &vita_texture->tex->gxm_colorsurface,
            &vita_texture->tex->gxm_depthstencil);
    }

    //    unset_clip_rectangle(data);

    data->drawing = SDL_TRUE;
}

static int VITA_GXM_SetVSync(SDL_Renderer *renderer, const int vsync)
{
    VITA_GXM_RenderData *data = renderer->driverdata;
    if (vsync) {
        data->displayData.wait_vblank = SDL_TRUE;
    } else {
        data->displayData.wait_vblank = SDL_FALSE;
    }
    return 0;
}

static int VITA_GXM_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
{
    VITA_GXM_RenderData *data;

    SDL_SetupRendererColorspace(renderer, create_props);

    if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) {
        return SDL_SetError("Unsupported output colorspace");
    }

    data = (VITA_GXM_RenderData *)SDL_calloc(1, sizeof(VITA_GXM_RenderData));
    if (!data) {
        return -1;
    }

    renderer->WindowEvent = VITA_GXM_WindowEvent;
    renderer->SupportsBlendMode = VITA_GXM_SupportsBlendMode;
    renderer->CreateTexture = VITA_GXM_CreateTexture;
    renderer->UpdateTexture = VITA_GXM_UpdateTexture;
#if SDL_HAVE_YUV
    renderer->UpdateTextureYUV = VITA_GXM_UpdateTextureYUV;
    renderer->UpdateTextureNV = VITA_GXM_UpdateTextureNV;
#endif
    renderer->LockTexture = VITA_GXM_LockTexture;
    renderer->UnlockTexture = VITA_GXM_UnlockTexture;
    renderer->SetTextureScaleMode = VITA_GXM_SetTextureScaleMode;
    renderer->SetRenderTarget = VITA_GXM_SetRenderTarget;
    renderer->QueueSetViewport = VITA_GXM_QueueNoOp;
    renderer->QueueSetDrawColor = VITA_GXM_QueueSetDrawColor;
    renderer->QueueDrawPoints = VITA_GXM_QueueDrawPoints;
    renderer->QueueDrawLines = VITA_GXM_QueueDrawLines;
    renderer->QueueGeometry = VITA_GXM_QueueGeometry;
    renderer->InvalidateCachedState = VITA_GXM_InvalidateCachedState;
    renderer->RunCommandQueue = VITA_GXM_RunCommandQueue;
    renderer->RenderReadPixels = VITA_GXM_RenderReadPixels;
    renderer->RenderPresent = VITA_GXM_RenderPresent;
    renderer->DestroyTexture = VITA_GXM_DestroyTexture;
    renderer->DestroyRenderer = VITA_GXM_DestroyRenderer;
    renderer->SetVSync = VITA_GXM_SetVSync;

    renderer->driverdata = data;
    VITA_GXM_InvalidateCachedState(renderer);
    renderer->window = window;

    renderer->name = VITA_GXM_RenderDriver.name;
    SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ABGR8888);
    SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_ARGB8888);
    SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGB565);
    SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_BGR565);
    SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_YV12);
    SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_IYUV);
    SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV12);
    SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV21);
    SDL_SetNumberProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER, 4096);

    data->initialized = SDL_TRUE;

#ifdef DEBUG_RAZOR
    sceSysmoduleLoadModule(SCE_SYSMODULE_RAZOR_HUD);
    sceSysmoduleLoadModule(SCE_SYSMODULE_RAZOR_CAPTURE);
#endif

    if (gxm_init(renderer) != 0) {
        SDL_free(data);
        return SDL_SetError("gxm_init failed");
    }

    return 0;
}

static void VITA_GXM_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event)
{
}

static SDL_bool VITA_GXM_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode)
{
    // only for custom modes. we build all modes on init, so no custom modes, sorry
    return SDL_FALSE;
}

static int VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props)
{
    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
    VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)SDL_calloc(1, sizeof(VITA_GXM_TextureData));

    if (!vita_texture) {
        return -1;
    }

    vita_texture->tex = create_gxm_texture(
        data,
        texture->w,
        texture->h,
        PixelFormatToVITAFMT(texture->format),
        (texture->access == SDL_TEXTUREACCESS_TARGET),
        &(vita_texture->w),
        &(vita_texture->h),
        &(vita_texture->pitch),
        &(vita_texture->wscale));

    if (!vita_texture->tex) {
        SDL_free(vita_texture);
        return SDL_OutOfMemory();
    }

    texture->driverdata = vita_texture;

    VITA_GXM_SetTextureScaleMode(renderer, texture, texture->scaleMode);

#if SDL_HAVE_YUV
    vita_texture->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12));
    vita_texture->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21));
#endif

    return 0;
}

static void VITA_GXM_SetYUVProfile(SDL_Renderer *renderer, SDL_Texture *texture)
{
    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
    int ret = 0;
    if (SDL_ISCOLORSPACE_MATRIX_BT601(texture->colorspace)) {
        if (SDL_ISCOLORSPACE_LIMITED_RANGE(texture->colorspace)) {
            ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT601_STANDARD);
        } else {
            ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT601_FULL_RANGE);
        }
    } else if (SDL_ISCOLORSPACE_MATRIX_BT709(texture->colorspace)) {
        if (SDL_ISCOLORSPACE_LIMITED_RANGE(texture->colorspace)) {
            ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT709_STANDARD);
        } else {
            ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT709_FULL_RANGE);
        }
    } else {
        SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Unsupported YUV colorspace\n");
    }

    if (ret < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Setting YUV profile failed: %x\n", ret);
    }
}

static int VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
                                  const SDL_Rect *rect, const void *pixels, int pitch)
{
    VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata;
    Uint8 *dst;
    int row, length, dpitch;

#if SDL_HAVE_YUV
    if (vita_texture->yuv || vita_texture->nv12) {
        VITA_GXM_SetYUVProfile(renderer, texture);
    }
#endif

    VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
    length = rect->w * SDL_BYTESPERPIXEL(texture->format);
    if (length == pitch && length == dpitch) {
        SDL_memcpy(dst, pixels, length * rect->h);
    } else {
        for (row = 0; row < rect->h; ++row) {
            SDL_memcpy(dst, pixels, length);
            pixels += pitch;
            dst += dpitch;
        }
    }

#if SDL_HAVE_YUV
    if (vita_texture->yuv) {
        void *Udst;
        void *Vdst;
        int uv_pitch = (dpitch + 1) / 2;
        int uv_src_pitch = (pitch + 1) / 2;
        SDL_Rect UVrect = { rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2 };

        // skip Y plane
        Uint8 *Dpixels = gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h);

        Udst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x;
        Vdst = Dpixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;

        length = UVrect.w;

        // U plane
        if (length == uv_src_pitch && length == uv_pitch) {
            SDL_memcpy(Udst, pixels, length * UVrect.h);
        } else {
            for (row = 0; row < UVrect.h; ++row) {
                SDL_memcpy(Udst, pixels, length);
                pixels += uv_src_pitch;
                Udst += uv_pitch;
            }
        }

        // V plane
        if (length == uv_src_pitch && length == uv_pitch) {
            SDL_memcpy(Vdst, pixels, length * UVrect.h);
        } else {
            for (row = 0; row < UVrect.h; ++row) {
                SDL_memcpy(Vdst, pixels, length);
                pixels += uv_src_pitch;
                Vdst += uv_pitch;
            }
        }

    } else if (vita_texture->nv12) {
        void *UVdst;
        int uv_pitch = 2 * ((dpitch + 1) / 2);
        int uv_src_pitch = 2 * ((pitch + 1) / 2);
        SDL_Rect UVrect = { rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2 };

        // skip Y plane
        void *Dpixels = (void *)((Uint8 *)gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
        UVdst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x;

        length = UVrect.w * 2;

        // UV plane
        if (length == uv_src_pitch && length == uv_pitch) {
            SDL_memcpy(UVdst, pixels, length * UVrect.h);
        } else {
            for (row = 0; row < UVrect.h; ++row) {
                SDL_memcpy(UVdst, pixels, length);
                pixels += uv_src_pitch;
                UVdst += uv_pitch;
            }
        }
    }
#endif

    return 0;
}

#if SDL_HAVE_YUV
static int VITA_GXM_UpdateTextureYUV(SDL_Renderer *renderer, SDL_Texture *texture,
                                     const SDL_Rect *rect,
                                     const Uint8 *Yplane, int Ypitch,
                                     const Uint8 *Uplane, int Upitch,
                                     const Uint8 *Vplane, int Vpitch)
{
    Uint8 *dst;
    int row, length, dpitch;
    SDL_Rect UVrect = { rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2 };

    VITA_GXM_SetYUVProfile(renderer, texture);

    // copy Y plane
    // obtain pixels via locking so that texture is flushed
    VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);

    length = rect->w;

    if (length == Ypitch && length == dpitch) {
        SDL_memcpy(dst, Yplane, length * rect->h);
    } else {
        for (row = 0; row < rect->h; ++row) {
            SDL_memcpy(dst, Yplane, length);
            Yplane += Ypitch;
            dst += dpitch;
        }
    }

    // U/V planes
    {
        void *Udst;
        void *Vdst;
        VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata;
        int uv_pitch = (dpitch + 1) / 2;

        // skip Y plane
        void *pixels = (void *)((Uint8 *)gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));

        if (texture->format == SDL_PIXELFORMAT_YV12) { // YVU
            Vdst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
            Udst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
        } else { // YUV
            Udst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
            Vdst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
        }

        length = UVrect.w;

        // U plane
        if (length == Upitch && length == uv_pitch) {
            SDL_memcpy(Udst, Uplane, length * UVrect.h);
        } else {
            for (row = 0; row < UVrect.h; ++row) {
                SDL_memcpy(Udst, Uplane, length);
                Uplane += Upitch;
                Udst += uv_pitch;
            }
        }

        // V plane
        if (length == Vpitch && length == uv_pitch) {
            SDL_memcpy(Vdst, Vplane, length * UVrect.h);
        } else {
            for (row = 0; row < UVrect.h; ++row) {
                SDL_memcpy(Vdst, Vplane, length);
                Vplane += Vpitch;
                Vdst += uv_pitch;
            }
        }
    }

    return 0;
}

static int VITA_GXM_UpdateTextureNV(SDL_Renderer *renderer, SDL_Texture *texture,
                                    const SDL_Rect *rect,
                                    const Uint8 *Yplane, int Ypitch,
                                    const Uint8 *UVplane, int UVpitch)
{

    Uint8 *dst;
    int row, length, dpitch;
    SDL_Rect UVrect = { rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2 };

    VITA_GXM_SetYUVProfile(renderer, texture);

    // copy Y plane
    VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);

    length = rect->w * SDL_BYTESPERPIXEL(texture->format);

    if (length == Ypitch && length == dpitch) {
        SDL_memcpy(dst, Yplane, length * rect->h);
    } else {
        for (row = 0; row < rect->h; ++row) {
            SDL_memcpy(dst, Yplane, length);
            Yplane += Ypitch;
            dst += dpitch;
        }
    }

    // UV plane
    {
        void *UVdst;
        VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata;
        int uv_pitch = 2 * ((dpitch + 1) / 2);

        // skip Y plane
        void *pixels = (void *)((Uint8 *)gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));

        UVdst = pixels + (UVrect.y * uv_pitch) + UVrect.x;

        length = UVrect.w * 2;

        // UV plane
        if (length == UVpitch && length == uv_pitch) {
            SDL_memcpy(UVdst, UVplane, length * UVrect.h);
        } else {
            for (row = 0; row < UVrect.h; ++row) {
                SDL_memcpy(UVdst, UVplane, length);
                UVplane += UVpitch;
                UVdst += uv_pitch;
            }
        }
    }

    return 0;
}

#endif

static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
                                const SDL_Rect *rect, void **pixels, int *pitch)
{
    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
    VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata;

    *pixels =
        (void *)((Uint8 *)gxm_texture_get_datap(vita_texture->tex) + (rect->y * vita_texture->pitch) + rect->x * SDL_BYTESPERPIXEL(texture->format));
    *pitch = vita_texture->pitch;

    // make sure that rendering is finished on render target textures
    if (vita_texture->tex->gxm_rendertarget) {
        sceGxmFinish(data->gxm_context);
    }

    return 0;
}

static void VITA_GXM_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{
    // No need to update texture data on ps vita.
    // VITA_GXM_LockTexture already returns a pointer to the texture pixels buffer.
    // This really improves framerate when using lock/unlock.
}

static void VITA_GXM_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode)
{
    VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata;

    /*
     set texture filtering according to scaleMode
     supported hint values are nearest (0, default) or linear (1)
     vitaScaleMode is either SCE_GXM_TEXTURE_FILTER_POINT (good for tile-map)
     or SCE_GXM_TEXTURE_FILTER_LINEAR (good for scaling)
     */

    int vitaScaleMode = (scaleMode == SDL_SCALEMODE_NEAREST
                             ? SCE_GXM_TEXTURE_FILTER_POINT
                             : SCE_GXM_TEXTURE_FILTER_LINEAR);
    gxm_texture_set_filters(vita_texture->tex, vitaScaleMode, vitaScaleMode);

    return;
}

static int VITA_GXM_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
{
    return 0;
}

static void VITA_GXM_SetBlendMode(VITA_GXM_RenderData *data, int blendMode)
{
    if (blendMode != data->currentBlendMode) {
        fragment_programs *in = &data->blendFragmentPrograms.blend_mode_blend;

        switch (blendMode) {
        case SDL_BLENDMODE_NONE:
            in = &data->blendFragmentPrograms.blend_mode_none;
            break;
        case SDL_BLENDMODE_BLEND:
            in = &data->blendFragmentPrograms.blend_mode_blend;
            break;
        case SDL_BLENDMODE_ADD:
            in = &data->blendFragmentPrograms.blend_mode_add;
            break;
        case SDL_BLENDMODE_MOD:
            in = &data->blendFragmentPrograms.blend_mode_mod;
            break;
        case SDL_BLENDMODE_MUL:
            in = &data->blendFragmentPrograms.blend_mode_mul;
            break;
        }
        data->colorFragmentProgram = in->color;
        data->textureFragmentProgram = in->texture;
        data->currentBlendMode = blendMode;
    }
}

static int VITA_GXM_QueueNoOp(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
{
    return 0;
}

static int VITA_GXM_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
{
    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;

    data->drawstate.color.r = cmd->data.color.color.r * cmd->data.color.color_scale;
    data->drawstate.color.g = cmd->data.color.color.g * cmd->data.color.color_scale;
    data->drawstate.color.b = cmd->data.color.color.b * cmd->data.color.color_scale;
    data->drawstate.color.a = cmd->data.color.color.a;

    return 0;
}

static int VITA_GXM_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
{
    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;

    SDL_FColor color = data->drawstate.color;

    color_vertex *vertex = (color_vertex *)pool_malloc(
        data,
        count * sizeof(color_vertex));

    cmd->data.draw.first = (size_t)vertex;
    cmd->data.draw.count = count;

    for (int i = 0; i < count; i++) {
        vertex[i].x = points[i].x;
        vertex[i].y = points[i].y;
        vertex[i].color = color;
    }

    return 0;
}

static int VITA_GXM_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
{
    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
    SDL_FColor color = data->drawstate.color;

    color_vertex *vertex = (color_vertex *)pool_malloc(
        data,
        (count - 1) * 2 * sizeof(color_vertex));

    cmd->data.draw.first = (size_t)vertex;
    cmd->data.draw.count = (count - 1) * 2;

    for (int i = 0; i < count - 1; i++) {
        vertex[i * 2].x = points[i].x;
        vertex[i * 2].y = points[i].y;
        vertex[i * 2].color = color;

        vertex[i * 2 + 1].x = points[i + 1].x;
        vertex[i * 2 + 1].y = points[i + 1].y;
        vertex[i * 2 + 1].color = color;
    }

    return 0;
}

static int VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
                                  const float *xy, int xy_stride, const SDL_FColor *color, int color_stride, const float *uv, int uv_stride,
                                  int num_vertices, const void *indices, int num_indices, int size_indices,
                                  float scale_x, float scale_y)
{
    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
    int i;
    int count = indices ? num_indices : num_vertices;
    const float color_scale = cmd->data.draw.color_scale;

    cmd->data.draw.count = count;
    size_indices = indices ? size_indices : 0;

    if (texture) {
        VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata;
        texture_vertex *vertices;

        vertices = (texture_vertex *)pool_malloc(
            data,
            count * sizeof(texture_vertex));

        if (!vertices) {
            return -1;
        }

        for (i = 0; i < count; i++) {
            int j;
            float *xy_;
            float *uv_;
            SDL_FColor col_;
            if (size_indices == 4) {
                j = ((const Uint32 *)indices)[i];
            } else if (size_indices == 2) {
                j = ((const Uint16 *)indices)[i];
            } else if (size_indices == 1) {
                j = ((const Uint8 *)indices)[i];
            } else {
                j = i;
            }

            xy_ = (float *)((char *)xy + j * xy_stride);
            col_ = *(SDL_FColor *)((char *)color + j * color_stride);
            uv_ = (float *)((char *)uv + j * uv_stride);

            col_.r *= color_scale;
            col_.g *= color_scale;
            col_.b *= color_scale;

            vertices[i].x = xy_[0] * scale_x;
            vertices[i].y = xy_[1] * scale_y;
            vertices[i].u = uv_[0] * vita_texture->wscale;
            vertices[i].v = uv_[1];
            vertices[i].color = col_;
        }

        cmd->data.draw.first = (size_t)vertices;

    } else {
        color_vertex *vertices;

        vertices = (color_vertex *)pool_malloc(
            data,
            count * sizeof(color_vertex));

        if (!vertices) {
            return -1;
        }

        for (i = 0; i < count; i++) {
            int j;
            float *xy_;
            SDL_FColor col_;
            if (size_indices == 4) {
                j = ((const Uint32 *)indices)[i];
            } else if (size_indices == 2) {
                j = ((const Uint16 *)indices)[i];
            } else if (size_indices == 1) {
                j = ((const Uint8 *)indices)[i];
            } else {
                j = i;
            }

            xy_ = (float *)((char *)xy + j * xy_stride);
            col_ = *(SDL_FColor *)((char *)color + j * color_stride);

            col_.r *= color_scale;
            col_.g *= color_scale;
            col_.b *= color_scale;

            vertices[i].x = xy_[0] * scale_x;
            vertices[i].y = xy_[1] * scale_y;
            vertices[i].color = col_;
        }
        cmd->data.draw.first = (size_t)vertices;
    }

    return 0;
}

static int VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
{
    void *color_buffer;
    SDL_FColor color;

    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
    unset_clip_rectangle(data);

    // set clear shaders
    data->drawstate.fragment_program = data->clearFragmentProgram;
    data->drawstate.vertex_program = data->clearVertexProgram;
    sceGxmSetVertexProgram(data->gxm_context, data->clearVertexProgram);
    sceGxmSetFragmentProgram(data->gxm_context, data->clearFragmentProgram);

    // set the clear color
    color = cmd->data.color.color;
    color.r *= cmd->data.color.color_scale;
    color.g *= cmd->data.color.color_scale;
    color.b *= cmd->data.color.color_scale;
    sceGxmReserveFragmentDefaultUniformBuffer(data->gxm_context, &color_buffer);
    sceGxmSetUniformDataF(color_buffer, data->clearClearColorParam, 0, 4, &color.r);

    // draw the clear triangle
    sceGxmSetVertexStream(data->gxm_context, 0, data->clearVertices);
    sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, 3);

    data->drawstate.cliprect_dirty = SDL_TRUE;
    return 0;
}

static int SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
{
    SDL_Texture *texture = cmd->data.draw.texture;
    const SDL_BlendMode blend = cmd->data.draw.blend;
    SceGxmFragmentProgram *fragment_program;
    SceGxmVertexProgram *vertex_program;
    SDL_bool matrix_updated = SDL_FALSE;
    SDL_bool program_updated = SDL_FALSE;

    if (data->drawstate.viewport_dirty) {
        const SDL_Rect *viewport = &data->drawstate.viewport;

        float sw = viewport->w / 2.f;
        float sh = viewport->h / 2.f;

        float x_scale = sw;
        float x_off = viewport->x + sw;
        float y_scale = -(sh);
        float y_off = viewport->y + sh;

        sceGxmSetViewport(data->gxm_context, x_off, x_scale, y_off, y_scale, 0.5f, 0.5f);

        if (viewport->w && viewport->h) {
            init_orthographic_matrix(data->ortho_matrix,
                                     (float)0,
                                     (float)viewport->w,
                                     (float)viewport->h,
                                     (float)0,
                                     0.0f, 1.0f);
            matrix_updated = SDL_TRUE;
        }

        data->drawstate.viewport_dirty = SDL_FALSE;
    }

    if (data->drawstate.cliprect_enabled_dirty) {
        if (!data->drawstate.cliprect_enabled) {
            unset_clip_rectangle(data);
        }
        data->drawstate.cliprect_enabled_dirty = SDL_FALSE;
    }

    if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
        const SDL_Rect *rect = &data->drawstate.cliprect;
        set_clip_rectangle(data, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
        data->drawstate.cliprect_dirty = SDL_FALSE;
    }

    VITA_GXM_SetBlendMode(data, blend); // do that first, to select appropriate shaders

    if (texture) {
        vertex_program = data->textureVertexProgram;
        fragment_program = data->textureFragmentProgram;
    } else {
        vertex_program = data->colorVertexProgram;
        fragment_program = data->colorFragmentProgram;
    }

    if (data->drawstate.vertex_program != vertex_program) {
        data->drawstate.vertex_program = vertex_program;
        sceGxmSetVertexProgram(data->gxm_context, vertex_program);
        program_updated = SDL_TRUE;
    }

    if (data->drawstate.fragment_program != fragment_program) {
        data->drawstate.fragment_program = fragment_program;
        sceGxmSetFragmentProgram(data->gxm_context, fragment_program);
        program_updated = SDL_TRUE;
    }

    if (program_updated || matrix_updated) {
        if (data->drawstate.fragment_program == data->textureFragmentProgram) {
            void *vertex_wvp_buffer;
            sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertex_wvp_buffer);
            sceGxmSetUniformDataF(vertex_wvp_buffer, data->textureWvpParam, 0, 16, data->ortho_matrix);
        } else { // color
            void *vertexDefaultBuffer;
            sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertexDefaultBuffer);
            sceGxmSetUniformDataF(vertexDefaultBuffer, data->colorWvpParam, 0, 16, data->ortho_matrix);
        }
    }

    if (texture != data->drawstate.texture) {
        if (texture) {
            VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)cmd->data.draw.texture->driverdata;
            sceGxmSetFragmentTexture(data->gxm_context, 0, &vita_texture->tex->gxm_tex);
        }
        data->drawstate.texture = texture;
    }

    /* all drawing commands use this */
    sceGxmSetVertexStream(data->gxm_context, 0, (const void *)cmd->data.draw.first);

    return 0;
}

static void VITA_GXM_InvalidateCachedState(SDL_Renderer *renderer)
{
    /* currently this doesn't do anything. If this needs to do something (and someone is mixing their own rendering calls in!), update this. */
}

static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
{
    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
    StartDrawing(renderer);

    data->drawstate.target = renderer->target;
    if (!data->drawstate.target) {
        int w, h;
        SDL_GetWindowSizeInPixels(renderer->window, &w, &h);
        if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) {
            data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc.
            data->drawstate.cliprect_dirty = SDL_TRUE;
            data->drawstate.drawablew = w;
            data->drawstate.drawableh = h;
        }
    }

    while (cmd) {
        switch (cmd->command) {

        case SDL_RENDERCMD_SETVIEWPORT:
        {
            SDL_Rect *viewport = &data->drawstate.viewport;
            if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) {
                SDL_copyp(viewport, &cmd->data.viewport.rect);
                data->drawstate.viewport_dirty = SDL_TRUE;
                data->drawstate.cliprect_dirty = SDL_TRUE;
            }
            break;
        }

        case SDL_RENDERCMD_SETCLIPRECT:
        {
            const SDL_Rect *rect = &cmd->data.cliprect.rect;
            if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
                data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
                data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
            }

            if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) {
                SDL_copyp(&data->drawstate.cliprect, rect);
                data->drawstate.cliprect_dirty = SDL_TRUE;
            }
            break;
        }

        case SDL_RENDERCMD_SETDRAWCOLOR:
        {
            break;
        }

        case SDL_RENDERCMD_CLEAR:
        {
            VITA_GXM_RenderClear(renderer, cmd);
            break;
        }

        case SDL_RENDERCMD_FILL_RECTS: /* unused */
            break;

        case SDL_RENDERCMD_COPY: /* unused */
            break;

        case SDL_RENDERCMD_COPY_EX: /* unused */
            break;

        case SDL_RENDERCMD_DRAW_POINTS:
        case SDL_RENDERCMD_DRAW_LINES:
        case SDL_RENDERCMD_GEOMETRY:
        {
            SDL_Texture *thistexture = cmd->data.draw.texture;
            SDL_BlendMode thisblend = cmd->data.draw.blend;
            const SDL_RenderCommandType thiscmdtype = cmd->command;
            SDL_RenderCommand *finalcmd = cmd;
            SDL_RenderCommand *nextcmd = cmd->next;
            size_t count = cmd->data.draw.count;
            int ret;
            while (nextcmd) {
                const SDL_RenderCommandType nextcmdtype = nextcmd->command;
                if (nextcmdtype != thiscmdtype) {
                    break; /* can't go any further on this draw call, different render command up next. */
                } else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) {
                    break; /* can't go any further on this draw call, different texture/blendmode copy up next. */
                } else {
                    finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */
                    count += nextcmd->data.draw.count;
                }
                nextcmd = nextcmd->next;
            }

            ret = SetDrawState(data, cmd);

            if (ret == 0) {
                int op = SCE_GXM_PRIMITIVE_TRIANGLES;

                if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) {
                    sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_POINT);
                    op = SCE_GXM_PRIMITIVE_POINTS;
                } else if (thiscmdtype == SDL_RENDERCMD_DRAW_LINES) {
                    sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_LINE);
                    op = SCE_GXM_PRIMITIVE_LINES;
                }

                sceGxmDraw(data->gxm_context, op, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, count);

                if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS || thiscmdtype == SDL_RENDERCMD_DRAW_LINES) {
                    sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_TRIANGLE_FILL);
                }
            }

            cmd = finalcmd; /* skip any copy commands we just combined in here. */
            break;
        }

        case SDL_RENDERCMD_NO_OP:
            break;
        }
        data->drawstate.last_command = cmd->command;
        cmd = cmd->next;
    }

    sceGxmEndScene(data->gxm_context, NULL, NULL);
    data->drawing = SDL_FALSE;

    return 0;
}

void read_pixels(int x, int y, size_t width, size_t height, void *data)
{
    SceDisplayFrameBuf pParam;
    int i, j;
    Uint32 *out32;
    Uint32 *in32;

    pParam.size = sizeof(SceDisplayFrameBuf);

    sceDisplayGetFrameBuf(&pParam, SCE_DISPLAY_SETBUF_NEXTFRAME);

    out32 = (Uint32 *)data;
    in32 = (Uint32 *)pParam.base;

    in32 += (x + y * pParam.pitch);

    for (i = 0; i < height; i++) {
        for (j = 0; j < width; j++) {
            out32[(height - (i + 1)) * width + j] = in32[j];
        }
        in32 += pParam.pitch;
    }
}

static SDL_Surface *VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
{
    Uint32 format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888;
    int w, h;
    SDL_Surface *surface;

    // TODO: read from texture rendertarget.
    if (renderer->target) {
        SDL_Unsupported();
        return NULL;
    }

    surface = SDL_CreateSurface(rect->w, rect->h, format);
    if (!surface) {
        return NULL;
    }

    SDL_GetCurrentRenderOutputSize(renderer, &w, &h);

    read_pixels(rect->x, renderer->target ? rect->y : (h - rect->y) - rect->h,
                rect->w, rect->h, surface->pixels);

    /* Flip the rows to be top-down if necessary */

    if (!renderer->target) {
        SDL_bool isstack;
        int length = rect->w * SDL_BYTESPERPIXEL(format);
        Uint8 *src = (Uint8 *)surface->pixels + (rect->h - 1) * surface->pitch;
        Uint8 *dst = (Uint8 *)surface->pixels;
        Uint8 *tmp = SDL_small_alloc(Uint8, length, &isstack);
        int rows = rect->h / 2;
        while (rows--) {
            SDL_memcpy(tmp, dst, length);
            SDL_memcpy(dst, src, length);
            SDL_memcpy(src, tmp, length);
            dst += surface->pitch;
            src -= surface->pitch;
        }
        SDL_small_free(tmp, isstack);
    }
    return surface;
}

static int VITA_GXM_RenderPresent(SDL_Renderer *renderer)
{
    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
    SceCommonDialogUpdateParam updateParam;

    data->displayData.address = data->displayBufferData[data->backBufferIndex];

    SDL_memset(&updateParam, 0, sizeof(updateParam));

    updateParam.renderTarget.colorFormat = VITA_GXM_COLOR_FORMAT;
    updateParam.renderTarget.surfaceType = SCE_GXM_COLOR_SURFACE_LINEAR;
    updateParam.renderTarget.width = VITA_GXM_SCREEN_WIDTH;
    updateParam.renderTarget.height = VITA_GXM_SCREEN_HEIGHT;
    updateParam.renderTarget.strideInPixels = VITA_GXM_SCREEN_STRIDE;

    updateParam.renderTarget.colorSurfaceData = data->displayBufferData[data->backBufferIndex];
    updateParam.renderTarget.depthSurfaceData = data->depthBufferData;

    updateParam.displaySyncObject = (SceGxmSyncObject *)data->displayBufferSync[data->backBufferIndex];

    sceCommonDialogUpdate(&updateParam);

#ifdef DEBUG_RAZOR
    sceGxmPadHeartbeat(
        (const SceGxmColorSurface *)&data->displaySurface[data->backBufferIndex],
        (SceGxmSyncObject *)data->displayBufferSync[data->backBufferIndex]);
#endif

    sceGxmDisplayQueueAddEntry(
        data->displayBufferSync[data->frontBufferIndex], // OLD fb
        data->displayBufferSync[data->backBufferIndex],  // NEW fb
        &data->displayData);

    // update buffer indices
    data->frontBufferIndex = data->backBufferIndex;
    data->backBufferIndex = (data->backBufferIndex + 1) % VITA_GXM_BUFFERS;
    data->pool_index = 0;

    data->current_pool = (data->current_pool + 1) % 2;
    return 0;
}

static void VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{
    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
    VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata;

    if (!data) {
        return;
    }

    if (!vita_texture) {
        return;
    }

    if (!vita_texture->tex) {
        return;
    }

    sceGxmFinish(data->gxm_context);

    free_gxm_texture(data, vita_texture->tex);

    SDL_free(vita_texture);

    texture->driverdata = NULL;
}

static void VITA_GXM_DestroyRenderer(SDL_Renderer *renderer)
{
    VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
    if (data) {
        if (!data->initialized) {
            return;
        }

        gxm_finish(renderer);

        data->initialized = SDL_FALSE;
        data->drawing = SDL_FALSE;
        SDL_free(data);
    }
}

#endif /* SDL_VIDEO_RENDER_VITA_GXM */
