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

#include "src/gpu/GrYUVATextureProxies.h"

#ifdef SK_DEBUG
static int num_channels(uint32_t channelFlags) {
    switch (channelFlags) {
        case kRed_SkColorChannelFlag        : return 1;
        case kAlpha_SkColorChannelFlag      : return 1;
        case kGray_SkColorChannelFlag       : return 1;
        case kGrayAlpha_SkColorChannelFlags : return 2;
        case kRG_SkColorChannelFlags        : return 2;
        case kRGB_SkColorChannelFlags       : return 3;
        case kRGBA_SkColorChannelFlags      : return 4;

        default:
            SkDEBUGFAILF("Unexpected channel combination 0x%08x", channelFlags);
            return 0;
    }
}
#endif

GrYUVATextureProxies::GrYUVATextureProxies(const SkYUVAInfo& yuvaInfo,
                                           sk_sp<GrSurfaceProxy> proxies[SkYUVAInfo::kMaxPlanes],
                                           GrSurfaceOrigin textureOrigin)
        : fYUVAInfo(yuvaInfo), fTextureOrigin(textureOrigin) {
    int n = yuvaInfo.numPlanes();
    if (n == 0) {
        *this = {};
        SkASSERT(!this->isValid());
        return;
    }
    uint32_t textureChannelMasks[SkYUVAInfo::kMaxPlanes];
    for (int i = 0; i < n; ++i) {
        if (!proxies[i]) {
            *this = {};
            SkASSERT(!this->isValid());
            return;
        }
        textureChannelMasks[i] = proxies[i]->backendFormat().channelMask();
    }
    fYUVALocations = yuvaInfo.toYUVALocations(textureChannelMasks);
    if (fYUVALocations[0].fPlane < 0) {
        *this = {};
        SkASSERT(!this->isValid());
        return;
    }
    fMipmapped = GrMipmapped::kYes;
    for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
        if (!proxies[i]) {
            *this = {};
            SkASSERT(!this->isValid());
            return;
        }
        SkASSERT(proxies[i]->asTextureProxy());
        if (proxies[i]->asTextureProxy()->mipmapped() == GrMipmapped::kNo) {
            fMipmapped = GrMipmapped::kNo;
        }
        fProxies[i] = std::move(proxies[i]);
    }
    SkASSERT(this->isValid());
}

GrYUVATextureProxies::GrYUVATextureProxies(const SkYUVAInfo& yuvaInfo,
                                           GrSurfaceProxyView views[SkYUVAInfo::kMaxPlanes],
                                           GrColorType colorTypes[SkYUVAInfo::kMaxPlanes])
        : fYUVAInfo(yuvaInfo) {
    uint32_t pixmapChannelMasks[SkYUVAInfo::kMaxPlanes];
    int n = yuvaInfo.numPlanes();
    if (n == 0) {
        *this = {};
        SkASSERT(!this->isValid());
        return;
    }
    fMipmapped = GrMipmapped::kYes;
    for (int i = 0; i < n; ++i) {
        pixmapChannelMasks[i] = GrColorTypeChannelFlags(colorTypes[i]);
        SkASSERT(num_channels(pixmapChannelMasks[i]) <=
                 num_channels(views[i].proxy()->backendFormat().channelMask()));
        if (!views[i] || views[i].origin() != views[0].origin()) {
            *this = {};
            SkASSERT(!this->isValid());
            return;
        }
        if (views[i].proxy()->asTextureProxy()->mipmapped() == GrMipmapped::kNo) {
            fMipmapped = GrMipmapped::kNo;
        }
    }
    // Initial locations refer to the CPU pixmap channels.
    fYUVALocations = yuvaInfo.toYUVALocations(pixmapChannelMasks);
    if (fYUVALocations[0].fPlane < 0) {
        *this = {};
        SkASSERT(!this->isValid());
        return;
    }

    // Run each location through the proxy view's swizzle to get the actual texture format channel.
    for (int i = 0; i < SkYUVAInfo::kYUVAChannelCount; ++i) {
        int plane = fYUVALocations[i].fPlane;
        if (plane >= 0) {
            int chanAsIdx = static_cast<int>(fYUVALocations[i].fChannel);
            switch (views[plane].swizzle()[chanAsIdx]) {
                case 'r': fYUVALocations[i].fChannel = SkColorChannel::kR; break;
                case 'g': fYUVALocations[i].fChannel = SkColorChannel::kG; break;
                case 'b': fYUVALocations[i].fChannel = SkColorChannel::kB; break;
                case 'a': fYUVALocations[i].fChannel = SkColorChannel::kA; break;

                default:
                    SkDEBUGFAILF("Unexpected swizzle value: %c", views[i].swizzle()[chanAsIdx]);
                    *this = {};
                    SkASSERT(!this->isValid());
                    return;
            }
        }
    }
    for (int i = 0; i < n; ++i) {
        fProxies[i] = views[i].detachProxy();
    }
    fTextureOrigin = views[0].origin();
    SkASSERT(this->isValid());
}
