//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CLProgram.cpp: Implements the cl::Program class.
//

#include "libANGLE/CLProgram.h"
#include "common/unsafe_buffers.h"

#include "libANGLE/CLContext.h"
#include "libANGLE/CLPlatform.h"
#include "libANGLE/cl_utils.h"

#include <cstring>

namespace cl
{

angle::Result Program::build(cl_uint numDevices,
                             const cl_device_id *deviceList,
                             const char *options,
                             ProgramCB pfnNotify,
                             void *userData)
{
    DevicePtrs devices;
    devices.reserve(numDevices);
    while (numDevices-- != 0u)
    {
        devices.emplace_back(&(*ANGLE_UNSAFE_TODO(deviceList++))->cast<Device>());
    }
    Program *notify = nullptr;
    if (pfnNotify != nullptr)
    {
        // This program has to be retained until the notify callback is called.
        retain();
        *mCallback = CallbackData(pfnNotify, userData);
        notify     = this;
    }
    return mImpl->build(devices, options, notify);
}

angle::Result Program::compile(cl_uint numDevices,
                               const cl_device_id *deviceList,
                               const char *options,
                               cl_uint numInputHeaders,
                               const cl_program *inputHeaders,
                               const char **headerIncludeNames,
                               ProgramCB pfnNotify,
                               void *userData)
{
    DevicePtrs devices;
    devices.reserve(numDevices);
    while (numDevices-- != 0u)
    {
        devices.emplace_back(&(*ANGLE_UNSAFE_TODO(deviceList++))->cast<Device>());
    }
    ProgramPtrs programs;
    programs.reserve(numInputHeaders);
    while (numInputHeaders-- != 0u)
    {
        programs.emplace_back(&(*ANGLE_UNSAFE_TODO(inputHeaders++))->cast<Program>());
    }
    Program *notify = nullptr;
    if (pfnNotify != nullptr)
    {
        // This program has to be retained until the notify callback is called.
        retain();
        *mCallback = CallbackData(pfnNotify, userData);
        notify     = this;
    }
    return mImpl->compile(devices, options, programs, headerIncludeNames, notify);
}

angle::Result Program::getInfo(ProgramInfo name,
                               size_t valueSize,
                               void *value,
                               size_t *valueSizeRet) const
{
    std::vector<cl_device_id> devices;
    cl_uint valUInt       = 0u;
    void *valPointer      = nullptr;
    const void *copyValue = nullptr;
    size_t copySize       = 0u;

    switch (name)
    {
        case ProgramInfo::ReferenceCount:
            valUInt   = getRefCount();
            copyValue = &valUInt;
            copySize  = sizeof(valUInt);
            break;
        case ProgramInfo::Context:
            valPointer = mContext->getNative();
            copyValue  = &valPointer;
            copySize   = sizeof(valPointer);
            break;
        case ProgramInfo::NumDevices:
            valUInt   = static_cast<decltype(valUInt)>(mDevices.size());
            copyValue = &valUInt;
            copySize  = sizeof(valUInt);
            break;
        case ProgramInfo::Devices:
            devices.reserve(mDevices.size());
            for (const DevicePtr &device : mDevices)
            {
                devices.emplace_back(device->getNative());
            }
            copyValue = devices.data();
            copySize  = devices.size() * sizeof(decltype(devices)::value_type);
            break;
        case ProgramInfo::Source:
            if (!mSource.empty())
            {
                copyValue = mSource.c_str();
                copySize  = mSource.length() + 1u;
            }
            break;
        case ProgramInfo::IL:
            if (!mIL.empty())
            {
                copyValue = mIL.c_str();
                copySize  = mIL.length() + 1u;
            }
            break;
        case ProgramInfo::BinarySizes:
        case ProgramInfo::Binaries:
        case ProgramInfo::NumKernels:
        case ProgramInfo::KernelNames:
        case ProgramInfo::ScopeGlobalCtorsPresent:
        case ProgramInfo::ScopeGlobalDtorsPresent:
            return mImpl->getInfo(name, valueSize, value, valueSizeRet);
        default:
            ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
    }

    if (value != nullptr)
    {
        // CL_INVALID_VALUE if size in bytes specified by param_value_size is < size of return type
        // as described in the Program Object Queries table and param_value is not NULL.
        if (valueSize < copySize)
        {
            ANGLE_CL_RETURN_ERROR(CL_INVALID_VALUE);
        }
        if (copyValue != nullptr)
        {
            ANGLE_UNSAFE_TODO(std::memcpy(value, copyValue, copySize));
        }
    }
    if (valueSizeRet != nullptr)
    {
        *valueSizeRet = copySize;
    }
    return angle::Result::Continue;
}

angle::Result Program::getBuildInfo(cl_device_id device,
                                    ProgramBuildInfo name,
                                    size_t valueSize,
                                    void *value,
                                    size_t *valueSizeRet) const
{
    return mImpl->getBuildInfo(device->cast<Device>(), name, valueSize, value, valueSizeRet);
}

cl_kernel Program::createKernel(const char *kernel_name)
{
    return Object::Create<Kernel>(*this, kernel_name);
}

angle::Result Program::createKernels(cl_uint numKernels, cl_kernel *kernels, cl_uint *numKernelsRet)
{
    if (kernels == nullptr)
    {
        numKernels = 0u;
    }
    rx::CLKernelImpl::CreateFuncs createFuncs;
    ANGLE_TRY(mImpl->createKernels(numKernels, createFuncs, numKernelsRet));
    KernelPtrs krnls;
    krnls.reserve(createFuncs.size());
    while (!createFuncs.empty())
    {
        krnls.emplace_back(new Kernel(*this, createFuncs.front()));
        if (krnls.back()->mImpl == nullptr)
        {
            return angle::Result::Stop;
        }
        createFuncs.pop_front();
    }
    for (KernelPtr &kernel : krnls)
    {
        *ANGLE_UNSAFE_TODO(kernels++) = kernel.release();
    }
    return angle::Result::Continue;
}

Program::~Program() = default;

void Program::callback()
{
    CallbackData callbackData;
    mCallback->swap(callbackData);
    const ProgramCB callback = callbackData.first;
    void *const userData     = callbackData.second;
    ASSERT(callback != nullptr);
    callback(this, userData);
    // This program can be released after the callback was called.
    if (release())
    {
        delete this;
    }
}

Program::Program(Context &context, std::string &&source)
    : mContext(&context),
      mDevices(context.getDevices()),
      mNumAttachedKernels(0u),
      mImpl(nullptr),
      mSource(std::move(source))
{
    ANGLE_CL_IMPL_TRY(context.getImpl().createProgramWithSource(*this, mSource, &mImpl));
}

Program::Program(Context &context, const void *il, size_t length)
    : mContext(&context),
      mDevices(context.getDevices()),
      mIL(static_cast<const char *>(il), length),
      mNumAttachedKernels(0u),
      mImpl(nullptr)
{
    ANGLE_CL_IMPL_TRY(context.getImpl().createProgramWithIL(*this, il, length, &mImpl));
}

Program::Program(Context &context,
                 DevicePtrs &&devices,
                 const size_t *lengths,
                 const unsigned char **binaries,
                 cl_int *binaryStatus)
    : mContext(&context), mDevices(std::move(devices)), mNumAttachedKernels(0u), mImpl(nullptr)
{
    ANGLE_CL_IMPL_TRY(
        context.getImpl().createProgramWithBinary(*this, lengths, binaries, binaryStatus, &mImpl));
}

Program::Program(Context &context, DevicePtrs &&devices, const char *kernelNames)
    : mContext(&context), mDevices(std::move(devices)), mNumAttachedKernels(0u), mImpl(nullptr)
{
    ANGLE_CL_IMPL_TRY(
        context.getImpl().createProgramWithBuiltInKernels(*this, kernelNames, &mImpl));
}

Program::Program(Context &context,
                 const DevicePtrs &devices,
                 const char *options,
                 const cl::ProgramPtrs &inputPrograms,
                 ProgramCB pfnNotify,
                 void *userData)
    : mContext(&context),
      mDevices(!devices.empty() ? devices : context.getDevices()),
      mNumAttachedKernels(0u),
      mImpl(nullptr)
{
    if (pfnNotify != nullptr)
    {
        // This program has to be retained until the notify callback is called.
        retain();
        *mCallback = CallbackData(pfnNotify, userData);
    }
    else
    {
        *mCallback = CallbackData();
    }
    ANGLE_CL_IMPL_TRY(context.getImpl().linkProgram(*this, mDevices, options, inputPrograms,
                                                    pfnNotify != nullptr ? this : nullptr, &mImpl));
}

}  // namespace cl
