/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkTypes.h"
#if defined(SK_BUILD_FOR_WIN) && !defined(_M_ARM64)

#include "src/utils/win/SkWGL.h"

#include "include/private/SkOnce.h"
#include "include/private/SkTDArray.h"
#include "src/core/SkTSearch.h"
#include "src/core/SkTSort.h"

bool SkWGLExtensions::hasExtension(HDC dc, const char* ext) const {
    if (nullptr == this->fGetExtensionsString) {
        return false;
    }
    if (!strcmp("WGL_ARB_extensions_string", ext)) {
        return true;
    }
    const char* extensionString = this->getExtensionsString(dc);
    size_t extLength = strlen(ext);

    while (true) {
        size_t n = strcspn(extensionString, " ");
        if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
            return true;
        }
        if (0 == extensionString[n]) {
            return false;
        }
        extensionString += n+1;
    }

    return false;
}

const char* SkWGLExtensions::getExtensionsString(HDC hdc) const {
    return fGetExtensionsString(hdc);
}

BOOL SkWGLExtensions::choosePixelFormat(HDC hdc,
                                        const int* piAttribIList,
                                        const FLOAT* pfAttribFList,
                                        UINT nMaxFormats,
                                        int* piFormats,
                                        UINT* nNumFormats) const {
    return fChoosePixelFormat(hdc, piAttribIList, pfAttribFList,
                              nMaxFormats, piFormats, nNumFormats);
}

BOOL SkWGLExtensions::getPixelFormatAttribiv(HDC hdc,
                                             int iPixelFormat,
                                             int iLayerPlane,
                                             UINT nAttributes,
                                             const int *piAttributes,
                                             int *piValues) const {
    return fGetPixelFormatAttribiv(hdc, iPixelFormat, iLayerPlane,
                                   nAttributes, piAttributes, piValues);
}

BOOL SkWGLExtensions::getPixelFormatAttribfv(HDC hdc,
                                             int iPixelFormat,
                                             int iLayerPlane,
                                             UINT nAttributes,
                                             const int *piAttributes,
                                             float *pfValues) const {
    return fGetPixelFormatAttribfv(hdc, iPixelFormat, iLayerPlane,
                                   nAttributes, piAttributes, pfValues);
}
HGLRC SkWGLExtensions::createContextAttribs(HDC hDC,
                                            HGLRC hShareContext,
                                            const int *attribList) const {
    return fCreateContextAttribs(hDC, hShareContext, attribList);
}

BOOL SkWGLExtensions::swapInterval(int interval) const {
    return fSwapInterval(interval);
}

HPBUFFER SkWGLExtensions::createPbuffer(HDC hDC,
                                        int iPixelFormat,
                                        int iWidth,
                                        int iHeight,
                                        const int *piAttribList) const {
    return fCreatePbuffer(hDC, iPixelFormat, iWidth, iHeight, piAttribList);
}

HDC SkWGLExtensions::getPbufferDC(HPBUFFER hPbuffer) const {
    return fGetPbufferDC(hPbuffer);
}

int SkWGLExtensions::releasePbufferDC(HPBUFFER hPbuffer, HDC hDC) const {
    return fReleasePbufferDC(hPbuffer, hDC);
}

BOOL SkWGLExtensions::destroyPbuffer(HPBUFFER hPbuffer) const {
    return fDestroyPbuffer(hPbuffer);
}

namespace {

struct PixelFormat {
    int fFormat;
    int fSampleCnt;
    int fChoosePixelFormatRank;
};

bool pf_less(const PixelFormat& a, const PixelFormat& b) {
    if (a.fSampleCnt < b.fSampleCnt) {
        return true;
    } else if (b.fSampleCnt < a.fSampleCnt) {
        return false;
    } else if (a.fChoosePixelFormatRank < b.fChoosePixelFormatRank) {
        return true;
    }
    return false;
}
}

int SkWGLExtensions::selectFormat(const int formats[],
                                  int formatCount,
                                  HDC dc,
                                  int desiredSampleCount) const {
    SkASSERT(desiredSampleCount >= 1);
    if (formatCount <= 0) {
        return -1;
    }
    PixelFormat desiredFormat = {
        0,
        desiredSampleCount,
        0,
    };
    SkTDArray<PixelFormat> rankedFormats;
    rankedFormats.setCount(formatCount);
    for (int i = 0; i < formatCount; ++i) {
        static const int kQueryAttr = SK_WGL_SAMPLES;
        int numSamples;
        this->getPixelFormatAttribiv(dc,
                                     formats[i],
                                     0,
                                     1,
                                     &kQueryAttr,
                                     &numSamples);
        rankedFormats[i].fFormat =  formats[i];
        rankedFormats[i].fSampleCnt = std::max(1, numSamples);
        rankedFormats[i].fChoosePixelFormatRank = i;
    }
    SkTQSort(rankedFormats.begin(), rankedFormats.end(), pf_less);
    int idx = SkTSearch<PixelFormat, pf_less>(rankedFormats.begin(),
                                              rankedFormats.count(),
                                              desiredFormat,
                                              sizeof(PixelFormat));
    if (idx < 0) {
        idx = ~idx;
    }
    // If the caller asked for non-MSAA fail if the closest format has MSAA.
    if (desiredSampleCount == 1 && rankedFormats[idx].fSampleCnt != 1) {
        return -1;
    }
    return rankedFormats[idx].fFormat;
}


namespace {

#if defined(UNICODE)
    #define STR_LIT(X) L## #X
#else
    #define STR_LIT(X) #X
#endif

#define DUMMY_CLASS STR_LIT("DummyClass")

HWND create_dummy_window() {
    HMODULE module = GetModuleHandle(nullptr);
    HWND dummy;
    RECT windowRect;
    windowRect.left = 0;
    windowRect.right = 8;
    windowRect.top = 0;
    windowRect.bottom = 8;

    WNDCLASS wc;

    wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc = (WNDPROC) DefWindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = module;
    wc.hIcon = LoadIcon(nullptr, IDI_WINLOGO);
    wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wc.hbrBackground = nullptr;
    wc.lpszMenuName = nullptr;
    wc.lpszClassName = DUMMY_CLASS;

    if(!RegisterClass(&wc)) {
        return 0;
    }

    DWORD style, exStyle;
    exStyle = WS_EX_CLIENTEDGE;
    style = WS_SYSMENU;

    AdjustWindowRectEx(&windowRect, style, false, exStyle);
    if(!(dummy = CreateWindowEx(exStyle,
                                DUMMY_CLASS,
                                STR_LIT("DummyWindow"),
                                WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style,
                                0, 0,
                                windowRect.right-windowRect.left,
                                windowRect.bottom-windowRect.top,
                                nullptr, nullptr,
                                module,
                                nullptr))) {
        UnregisterClass(DUMMY_CLASS, module);
        return nullptr;
    }
    ShowWindow(dummy, SW_HIDE);

    return dummy;
}

void destroy_dummy_window(HWND dummy) {
    DestroyWindow(dummy);
    HMODULE module = GetModuleHandle(nullptr);
    UnregisterClass(DUMMY_CLASS, module);
}
}

#define GET_PROC(NAME, SUFFIX) f##NAME = \
                     (NAME##Proc) wglGetProcAddress("wgl" #NAME #SUFFIX)


SkWGLExtensions::GetExtensionsStringProc SkWGLExtensions::fGetExtensionsString = nullptr;
SkWGLExtensions::ChoosePixelFormatProc SkWGLExtensions::fChoosePixelFormat = nullptr;
SkWGLExtensions::GetPixelFormatAttribfvProc SkWGLExtensions::fGetPixelFormatAttribfv = nullptr;
SkWGLExtensions::GetPixelFormatAttribivProc SkWGLExtensions::fGetPixelFormatAttribiv = nullptr;
SkWGLExtensions::CreateContextAttribsProc SkWGLExtensions::fCreateContextAttribs = nullptr;
SkWGLExtensions::SwapIntervalProc SkWGLExtensions::fSwapInterval = nullptr;
SkWGLExtensions::CreatePbufferProc SkWGLExtensions::fCreatePbuffer = nullptr;
SkWGLExtensions::GetPbufferDCProc SkWGLExtensions::fGetPbufferDC = nullptr;
SkWGLExtensions::ReleasePbufferDCProc SkWGLExtensions::fReleasePbufferDC = nullptr;
SkWGLExtensions::DestroyPbufferProc SkWGLExtensions::fDestroyPbuffer = nullptr;

SkWGLExtensions::SkWGLExtensions() {
    // We cache these function pointers once, and then reuse them. That's possibly incorrect if
    // there are multiple GPUs, or if we intend to use these for rendering contexts of different
    // pixel formats (where wglGetProcAddress is not guaranteed to return the same pointer).
    static SkOnce once;
    once([] {
        HDC prevDC = wglGetCurrentDC();
        HGLRC prevGLRC = wglGetCurrentContext();

        PIXELFORMATDESCRIPTOR dummyPFD;

        ZeroMemory(&dummyPFD, sizeof(dummyPFD));
        dummyPFD.nSize = sizeof(dummyPFD);
        dummyPFD.nVersion = 1;
        dummyPFD.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
        dummyPFD.iPixelType = PFD_TYPE_RGBA;
        dummyPFD.cColorBits  = 32;
        dummyPFD.cDepthBits  = 0;
        dummyPFD.cStencilBits = 8;
        dummyPFD.iLayerType = PFD_MAIN_PLANE;
        HWND dummyWND = create_dummy_window();
        if (dummyWND) {
            HDC dummyDC = GetDC(dummyWND);
            int dummyFormat = ChoosePixelFormat(dummyDC, &dummyPFD);
            SetPixelFormat(dummyDC, dummyFormat, &dummyPFD);
            HGLRC dummyGLRC = wglCreateContext(dummyDC);
            SkASSERT(dummyGLRC);
            wglMakeCurrent(dummyDC, dummyGLRC);

            GET_PROC(GetExtensionsString, ARB);
            GET_PROC(ChoosePixelFormat, ARB);
            GET_PROC(GetPixelFormatAttribiv, ARB);
            GET_PROC(GetPixelFormatAttribfv, ARB);
            GET_PROC(CreateContextAttribs, ARB);
            GET_PROC(SwapInterval, EXT);
            GET_PROC(CreatePbuffer, ARB);
            GET_PROC(GetPbufferDC, ARB);
            GET_PROC(ReleasePbufferDC, ARB);
            GET_PROC(DestroyPbuffer, ARB);

            wglMakeCurrent(dummyDC, nullptr);
            wglDeleteContext(dummyGLRC);
            destroy_dummy_window(dummyWND);
        }

        wglMakeCurrent(prevDC, prevGLRC);
    });
}

///////////////////////////////////////////////////////////////////////////////

static void get_pixel_formats_to_try(HDC dc, const SkWGLExtensions& extensions,
                                     bool doubleBuffered, int msaaSampleCount, bool deepColor,
                                     int formatsToTry[2]) {
    auto appendAttr = [](SkTDArray<int>& attrs, int attr, int value) {
        attrs.push_back(attr);
        attrs.push_back(value);
    };

    SkTDArray<int> iAttrs;
    appendAttr(iAttrs, SK_WGL_DRAW_TO_WINDOW, TRUE);
    appendAttr(iAttrs, SK_WGL_DOUBLE_BUFFER, (doubleBuffered ? TRUE : FALSE));
    appendAttr(iAttrs, SK_WGL_ACCELERATION, SK_WGL_FULL_ACCELERATION);
    appendAttr(iAttrs, SK_WGL_SUPPORT_OPENGL, TRUE);
    if (deepColor) {
        appendAttr(iAttrs, SK_WGL_RED_BITS, 10);
        appendAttr(iAttrs, SK_WGL_GREEN_BITS, 10);
        appendAttr(iAttrs, SK_WGL_BLUE_BITS, 10);
        appendAttr(iAttrs, SK_WGL_ALPHA_BITS, 2);
    } else {
        appendAttr(iAttrs, SK_WGL_COLOR_BITS, 24);
        appendAttr(iAttrs, SK_WGL_ALPHA_BITS, 8);
    }
    appendAttr(iAttrs, SK_WGL_STENCIL_BITS, 8);

    float fAttrs[] = {0, 0};

    // Get a MSAA format if requested and possible.
    if (msaaSampleCount > 0 &&
        extensions.hasExtension(dc, "WGL_ARB_multisample")) {
        SkTDArray<int> msaaIAttrs = iAttrs;
        appendAttr(msaaIAttrs, SK_WGL_SAMPLE_BUFFERS, TRUE);
        appendAttr(msaaIAttrs, SK_WGL_SAMPLES, msaaSampleCount);
        appendAttr(msaaIAttrs, 0, 0);
        unsigned int num;
        int formats[64];
        extensions.choosePixelFormat(dc, msaaIAttrs.begin(), fAttrs, 64, formats, &num);
        num = std::min(num, 64U);
        formatsToTry[0] = extensions.selectFormat(formats, num, dc, msaaSampleCount);
    }

    // Get a non-MSAA format
    int* format = -1 == formatsToTry[0] ? &formatsToTry[0] : &formatsToTry[1];
    unsigned int num;
    appendAttr(iAttrs, 0, 0);
    extensions.choosePixelFormat(dc, iAttrs.begin(), fAttrs, 1, format, &num);
}

static HGLRC create_gl_context(HDC dc, const SkWGLExtensions& extensions,
                               SkWGLContextRequest contextType, HGLRC shareContext) {
    HDC prevDC = wglGetCurrentDC();
    HGLRC prevGLRC = wglGetCurrentContext();

    HGLRC glrc = nullptr;
    if (kGLES_SkWGLContextRequest == contextType) {
        if (!extensions.hasExtension(dc, "WGL_EXT_create_context_es2_profile")) {
            wglMakeCurrent(prevDC, prevGLRC);
            return nullptr;
        }
        static const int glesAttribs[] = {
            SK_WGL_CONTEXT_MAJOR_VERSION, 3,
            SK_WGL_CONTEXT_MINOR_VERSION, 0,
            SK_WGL_CONTEXT_PROFILE_MASK,  SK_WGL_CONTEXT_ES2_PROFILE_BIT,
            0,
        };
        glrc = extensions.createContextAttribs(dc, shareContext, glesAttribs);
        if (nullptr == glrc) {
            wglMakeCurrent(prevDC, prevGLRC);
            return nullptr;
        }
    } else {
        if (kGLPreferCoreProfile_SkWGLContextRequest == contextType &&
            extensions.hasExtension(dc, "WGL_ARB_create_context")) {
            static const int kCoreGLVersions[] = {
                4, 3,
                4, 2,
                4, 1,
                4, 0,
                3, 3,
                3, 2,
            };
            int coreProfileAttribs[] = {
                SK_WGL_CONTEXT_MAJOR_VERSION, -1,
                SK_WGL_CONTEXT_MINOR_VERSION, -1,
                SK_WGL_CONTEXT_PROFILE_MASK,  SK_WGL_CONTEXT_CORE_PROFILE_BIT,
                0,
            };
            for (size_t v = 0; v < SK_ARRAY_COUNT(kCoreGLVersions) / 2; ++v) {
                coreProfileAttribs[1] = kCoreGLVersions[2 * v];
                coreProfileAttribs[3] = kCoreGLVersions[2 * v + 1];
                glrc = extensions.createContextAttribs(dc, shareContext, coreProfileAttribs);
                if (glrc) {
                    break;
                }
            }
        }
    }

    if (nullptr == glrc) {
        glrc = wglCreateContext(dc);
        if (shareContext) {
            if (!wglShareLists(shareContext, glrc)) {
                wglDeleteContext(glrc);
                return nullptr;
            }
        }
    }
    SkASSERT(glrc);

    wglMakeCurrent(prevDC, prevGLRC);

    return glrc;
}

HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, bool deepColor,
                         SkWGLContextRequest contextType, HGLRC shareContext) {
    SkWGLExtensions extensions;
    if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format")) {
        return nullptr;
    }

    BOOL set = FALSE;

    int pixelFormatsToTry[] = { -1, -1 };
    get_pixel_formats_to_try(dc, extensions, true, msaaSampleCount, deepColor, pixelFormatsToTry);
    for (size_t f = 0;
         !set && -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFormatsToTry);
         ++f) {
        PIXELFORMATDESCRIPTOR pfd;
        DescribePixelFormat(dc, pixelFormatsToTry[f], sizeof(pfd), &pfd);
        set = SetPixelFormat(dc, pixelFormatsToTry[f], &pfd);
    }

    if (!set) {
        return nullptr;
    }

    return create_gl_context(dc, extensions, contextType, shareContext);
}

sk_sp<SkWGLPbufferContext> SkWGLPbufferContext::Create(HDC parentDC,
                                                       SkWGLContextRequest contextType,
                                                       HGLRC shareContext) {
    SkWGLExtensions extensions;
    if (!extensions.hasExtension(parentDC, "WGL_ARB_pixel_format") ||
        !extensions.hasExtension(parentDC, "WGL_ARB_pbuffer")) {
        return nullptr;
    }

    // We cache the pixel formats once, and then reuse them. That's possibly incorrect if
    // there are multiple GPUs, but this function is always called with a freshly made,
    // identically constructed HDC (see WinGLTestContext).
    //
    // We only store two potential pixel formats, one for single buffer, one for double buffer.
    // We never ask for MSAA, so we don't need the second pixel format for each buffering state.
    static int gPixelFormats[2] = { -1, -1 };
    static SkOnce once;
    once([=] {
        {
            // Single buffer
            int pixelFormatsToTry[2] = { -1, -1 };
            get_pixel_formats_to_try(parentDC, extensions, false, 0, false, pixelFormatsToTry);
            gPixelFormats[0] = pixelFormatsToTry[0];
        }
        {
            // Double buffer
            int pixelFormatsToTry[2] = { -1, -1 };
            get_pixel_formats_to_try(parentDC, extensions, true, 0, false, pixelFormatsToTry);
            gPixelFormats[1] = pixelFormatsToTry[0];
        }
    });

    // try for single buffer first
    for (int pixelFormat : gPixelFormats) {
        if (-1 == pixelFormat) {
            continue;
        }
        HPBUFFER pbuf = extensions.createPbuffer(parentDC, pixelFormat, 1, 1, nullptr);
        if (0 != pbuf) {
            HDC dc = extensions.getPbufferDC(pbuf);
            if (dc) {
                HGLRC glrc = create_gl_context(dc, extensions, contextType, shareContext);
                if (glrc) {
                    return sk_sp<SkWGLPbufferContext>(new SkWGLPbufferContext(pbuf, dc, glrc));
                }
                extensions.releasePbufferDC(pbuf, dc);
            }
            extensions.destroyPbuffer(pbuf);
        }
    }
    return nullptr;
}

SkWGLPbufferContext::~SkWGLPbufferContext() {
    SkASSERT(fExtensions.hasExtension(fDC, "WGL_ARB_pbuffer"));
    wglDeleteContext(fGLRC);
    fExtensions.releasePbufferDC(fPbuffer, fDC);
    fExtensions.destroyPbuffer(fPbuffer);
}

SkWGLPbufferContext::SkWGLPbufferContext(HPBUFFER pbuffer, HDC dc, HGLRC glrc)
    : fPbuffer(pbuffer)
    , fDC(dc)
    , fGLRC(glrc) {
}

#endif//defined(SK_BUILD_FOR_WIN)
