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

#include "GrTextureToYUVPlanes.h"
#include "effects/GrSimpleTextureEffect.h"
#include "effects/GrYUVEffect.h"
#include "GrClip.h"
#include "GrContext.h"
#include "GrRenderTargetContext.h"
#include "GrPaint.h"
#include "GrTextureProvider.h"

namespace {
    using MakeFPProc = sk_sp<GrFragmentProcessor> (*)(sk_sp<GrFragmentProcessor>,
                                                      SkYUVColorSpace colorSpace);
};

static bool convert_texture(GrTexture* src, GrRenderTargetContext* dst, int dstW, int dstH,
                            SkYUVColorSpace colorSpace, MakeFPProc proc) {

    SkScalar xScale = SkIntToScalar(src->width()) / dstW;
    SkScalar yScale = SkIntToScalar(src->height()) / dstH;
    GrSamplerParams::FilterMode filter;
    if (dstW == src->width() && dstW == src->height()) {
        filter = GrSamplerParams::kNone_FilterMode;
    } else {
        filter = GrSamplerParams::kBilerp_FilterMode;
    }

    sk_sp<GrFragmentProcessor> fp(
            GrSimpleTextureEffect::Make(src, nullptr, SkMatrix::MakeScale(xScale, yScale), filter));
    if (!fp) {
        return false;
    }
    fp = proc(std::move(fp), colorSpace);
    if (!fp) {
        return false;
    }
    GrPaint paint;
    paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
    paint.addColorFragmentProcessor(std::move(fp));
    dst->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
                  SkRect::MakeIWH(dstW, dstH));
    return true;
}

bool GrTextureToYUVPlanes(GrTexture* texture, const SkISize sizes[3], void* const planes[3],
                          const size_t rowBytes[3], SkYUVColorSpace colorSpace) {
    if (GrContext* context = texture->getContext()) {
        // Depending on the relative sizes of the y, u, and v planes we may do 1 to 3 draws/
        // readbacks.
        sk_sp<GrRenderTargetContext> yuvRenderTargetContext;
        sk_sp<GrRenderTargetContext> yRenderTargetContext;
        sk_sp<GrRenderTargetContext> uvRenderTargetContext;
        sk_sp<GrRenderTargetContext> uRenderTargetContext;
        sk_sp<GrRenderTargetContext> vRenderTargetContext;

        // We issue draw(s) to convert from RGBA to Y, U, and V. All three planes may have different
        // sizes however we optimize for two other cases - all planes are the same (1 draw to YUV),
        // and U and V are the same but Y differs (2 draws, one for Y, one for UV).
        if (sizes[0] == sizes[1] && sizes[1] == sizes[2]) {
            yuvRenderTargetContext = context->makeRenderTargetContextWithFallback(
                                                                           SkBackingFit::kApprox,
                                                                           sizes[0].fWidth,
                                                                           sizes[0].fHeight,
                                                                           kRGBA_8888_GrPixelConfig,
                                                                           nullptr);
            if (!yuvRenderTargetContext) {
                return false;
            }
        } else {
            yRenderTargetContext = context->makeRenderTargetContextWithFallback(
                                                                             SkBackingFit::kApprox,
                                                                             sizes[0].fWidth,
                                                                             sizes[0].fHeight,
                                                                             kAlpha_8_GrPixelConfig,
                                                                             nullptr);
            if (!yRenderTargetContext) {
                return false;
            }
            if (sizes[1] == sizes[2]) {
                // TODO: Add support for GL_RG when available.
                uvRenderTargetContext = context->makeRenderTargetContextWithFallback(
                                                                           SkBackingFit::kApprox,
                                                                           sizes[1].fWidth,
                                                                           sizes[1].fHeight,
                                                                           kRGBA_8888_GrPixelConfig,
                                                                           nullptr);
                if (!uvRenderTargetContext) {
                    return false;
                }
            } else {
                uRenderTargetContext = context->makeRenderTargetContextWithFallback(
                                                                             SkBackingFit::kApprox,
                                                                             sizes[1].fWidth,
                                                                             sizes[1].fHeight,
                                                                             kAlpha_8_GrPixelConfig,
                                                                             nullptr);
                vRenderTargetContext = context->makeRenderTargetContextWithFallback(
                                                                             SkBackingFit::kApprox,
                                                                             sizes[2].fWidth,
                                                                             sizes[2].fHeight,
                                                                             kAlpha_8_GrPixelConfig,
                                                                             nullptr);
                if (!uRenderTargetContext || !vRenderTargetContext) {
                    return false;
                }
            }
        }

        // Do all the draws before any readback.
        if (yuvRenderTargetContext) {
            if (!convert_texture(texture, yuvRenderTargetContext.get(),
                                 sizes[0].fWidth, sizes[0].fHeight,
                                 colorSpace, GrYUVEffect::MakeRGBToYUV)) {
                return false;
            }
        } else {
            SkASSERT(yRenderTargetContext);
            if (!convert_texture(texture, yRenderTargetContext.get(),
                                 sizes[0].fWidth, sizes[0].fHeight,
                                 colorSpace, GrYUVEffect::MakeRGBToY)) {
                return false;
            }
            if (uvRenderTargetContext) {
                if (!convert_texture(texture, uvRenderTargetContext.get(),
                                     sizes[1].fWidth, sizes[1].fHeight,
                                     colorSpace,  GrYUVEffect::MakeRGBToUV)) {
                    return false;
                }
            } else {
                SkASSERT(uRenderTargetContext && vRenderTargetContext);
                if (!convert_texture(texture, uRenderTargetContext.get(),
                                     sizes[1].fWidth, sizes[1].fHeight,
                                     colorSpace, GrYUVEffect::MakeRGBToU)) {
                    return false;
                }
                if (!convert_texture(texture, vRenderTargetContext.get(),
                                     sizes[2].fWidth, sizes[2].fHeight,
                                     colorSpace, GrYUVEffect::MakeRGBToV)) {
                    return false;
                }
            }
        }

        if (yuvRenderTargetContext) {
            SkASSERT(sizes[0] == sizes[1] && sizes[1] == sizes[2]);
            SkISize yuvSize = sizes[0];
            // We have no kRGB_888 pixel format, so readback rgba and then copy three channels.
            SkAutoSTMalloc<128 * 128, uint32_t> tempYUV(yuvSize.fWidth * yuvSize.fHeight);

            const SkImageInfo ii = SkImageInfo::Make(yuvSize.fWidth, yuvSize.fHeight,
                                                     kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
            if (!yuvRenderTargetContext->readPixels(ii, tempYUV.get(), 0, 0, 0)) {
                return false;
            }
            size_t yRowBytes = rowBytes[0] ? rowBytes[0] : yuvSize.fWidth;
            size_t uRowBytes = rowBytes[1] ? rowBytes[1] : yuvSize.fWidth;
            size_t vRowBytes = rowBytes[2] ? rowBytes[2] : yuvSize.fWidth;
            if (yRowBytes < (size_t)yuvSize.fWidth || uRowBytes < (size_t)yuvSize.fWidth ||
                vRowBytes < (size_t)yuvSize.fWidth) {
                return false;
            }
            for (int j = 0; j < yuvSize.fHeight; ++j) {
                for (int i = 0; i < yuvSize.fWidth; ++i) {
                    // These writes could surely be made more efficient.
                    uint32_t y = GrColorUnpackR(tempYUV.get()[j * yuvSize.fWidth + i]);
                    uint32_t u = GrColorUnpackG(tempYUV.get()[j * yuvSize.fWidth + i]);
                    uint32_t v = GrColorUnpackB(tempYUV.get()[j * yuvSize.fWidth + i]);
                    uint8_t* yLoc = ((uint8_t*)planes[0]) + j * yRowBytes + i;
                    uint8_t* uLoc = ((uint8_t*)planes[1]) + j * uRowBytes + i;
                    uint8_t* vLoc = ((uint8_t*)planes[2]) + j * vRowBytes + i;
                    *yLoc = y;
                    *uLoc = u;
                    *vLoc = v;
                }
            }
            return true;
        } else {
            SkASSERT(yRenderTargetContext);

            SkImageInfo ii = SkImageInfo::MakeA8(sizes[0].fWidth, sizes[0].fHeight);
            if (!yRenderTargetContext->readPixels(ii, planes[0], rowBytes[0], 0, 0)) {
                return false;
            }

            if (uvRenderTargetContext) {
                SkASSERT(sizes[1].fWidth == sizes[2].fWidth);
                SkISize uvSize = sizes[1];
                // We have no kRG_88 pixel format, so readback rgba and then copy two channels.
                SkAutoSTMalloc<128 * 128, uint32_t> tempUV(uvSize.fWidth * uvSize.fHeight);

                ii = SkImageInfo::Make(uvSize.fWidth, uvSize.fHeight,
                                       kRGBA_8888_SkColorType, kOpaque_SkAlphaType);

                if (!uvRenderTargetContext->readPixels(ii, tempUV.get(), 0, 0, 0)) {
                    return false;
                }

                size_t uRowBytes = rowBytes[1] ? rowBytes[1] : uvSize.fWidth;
                size_t vRowBytes = rowBytes[2] ? rowBytes[2] : uvSize.fWidth;
                if (uRowBytes < (size_t)uvSize.fWidth || vRowBytes < (size_t)uvSize.fWidth) {
                    return false;
                }
                for (int j = 0; j < uvSize.fHeight; ++j) {
                    for (int i = 0; i < uvSize.fWidth; ++i) {
                        // These writes could surely be made more efficient.
                        uint32_t u = GrColorUnpackR(tempUV.get()[j * uvSize.fWidth + i]);
                        uint32_t v = GrColorUnpackG(tempUV.get()[j * uvSize.fWidth + i]);
                        uint8_t* uLoc = ((uint8_t*)planes[1]) + j * uRowBytes + i;
                        uint8_t* vLoc = ((uint8_t*)planes[2]) + j * vRowBytes + i;
                        *uLoc = u;
                        *vLoc = v;
                    }
                }
                return true;
            } else {
                SkASSERT(uRenderTargetContext && vRenderTargetContext);

                ii = SkImageInfo::MakeA8(sizes[1].fWidth, sizes[1].fHeight);
                if (!uRenderTargetContext->readPixels(ii, planes[1], rowBytes[1], 0, 0)) {
                    return false;
                }

                ii = SkImageInfo::MakeA8(sizes[2].fWidth, sizes[2].fHeight);
                if (!vRenderTargetContext->readPixels(ii, planes[2], rowBytes[2], 0, 0)) {
                    return false;
                }

                return true;
            }
        }
    }
    return false;
}
