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

// This test only works with the GPU backend.

#include "gm/gm.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/core/SkYUVAIndex.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrTypes.h"
#include "include/private/SkTo.h"
#include "src/core/SkMathPriv.h"
#include "src/core/SkYUVMath.h"
#include "tools/Resources.h"
#include "tools/gpu/YUVUtils.h"

class GrRenderTargetContext;

namespace skiagm {
class ImageFromYUVTextures : public GpuGM {
public:
    ImageFromYUVTextures() {
        this->setBGColor(0xFFFFFFFF);
    }

protected:
    SkString onShortName() override {
        return SkString("image_from_yuv_textures");
    }

    SkISize onISize() override { return {1420, 610}; }

    static std::unique_ptr<sk_gpu_test::LazyYUVImage> CreatePlanes(const char* name) {
        SkBitmap bmp;
        if (!GetResourceAsBitmap(name, &bmp)) {
            return {};
        }
        if (bmp.colorType() != kRGBA_8888_SkColorType) {
            auto info = bmp.info().makeColorType(kRGBA_8888_SkColorType);
            SkBitmap copy;
            copy.allocPixels(info);
            SkAssertResult(bmp.readPixels(copy.pixmap()));
            bmp = copy;
        }
        SkYUVAPixmapInfo pixmapInfo({bmp.dimensions(),
                                     SkYUVAInfo::PlanarConfig::kY_U_V_A_4204,
                                     kJPEG_Full_SkYUVColorSpace},
                                    SkYUVAPixmapInfo::DataType::kUnorm8,
                                    nullptr);
        auto pixmaps = SkYUVAPixmaps::Allocate(pixmapInfo);

        unsigned char* yuvPixels[] = {
                static_cast<unsigned char*>(pixmaps.planes()[0].writable_addr()),
                static_cast<unsigned char*>(pixmaps.planes()[1].writable_addr()),
                static_cast<unsigned char*>(pixmaps.planes()[2].writable_addr()),
                static_cast<unsigned char*>(pixmaps.planes()[3].writable_addr()),
        };

        float m[20];
        SkColorMatrix_RGB2YUV(pixmaps.yuvaInfo().yuvColorSpace(), m);
        // Here we encode using the kJPEG_SkYUVColorSpace (i.e., full-swing Rec 601) even though
        // we will draw it with all the supported yuv color spaces when converted back to RGB
        for (int j = 0; j < pixmaps.planes()[0].height(); ++j) {
            for (int i = 0; i < pixmaps.planes()[0].width(); ++i) {
                auto rgba = *bmp.getAddr32(i, j);
                auto r = (rgba & 0x000000ff) >>  0;
                auto g = (rgba & 0x0000ff00) >>  8;
                auto b = (rgba & 0x00ff0000) >> 16;
                auto a = (rgba & 0xff000000) >> 24;
                yuvPixels[0][j*pixmaps.planes()[0].width() + i] = SkToU8(
                        sk_float_round2int(m[0]*r + m[1]*g + m[2]*b + m[3]*a + 255*m[4]));
                yuvPixels[3][j*pixmaps.planes()[0].width() + i] = SkToU8(sk_float_round2int(
                        m[15]*r + m[16]*g + m[17]*b + m[18]*a + 255*m[19]));
            }
        }
        for (int j = 0; j < pixmaps.planes()[1].height(); ++j) {
            for (int i = 0; i < pixmaps.planes()[1].width(); ++i) {
                // Average together 4 pixels of RGB.
                int rgba[] = {0, 0, 0, 0};
                int denom = 0;
                int ylimit = std::min(2*j + 2, pixmaps.planes()[0].height());
                int xlimit = std::min(2*i + 2, pixmaps.planes()[0].width());
                for (int y = 2*j; y < ylimit; ++y) {
                    for (int x = 2*i; x < xlimit; ++x) {
                        auto src = *bmp.getAddr32(x, y);
                        rgba[0] += (src & 0x000000ff) >> 0;
                        rgba[1] += (src & 0x0000ff00) >> 8;
                        rgba[2] += (src & 0x00ff0000) >> 16;
                        rgba[3] += (src & 0xff000000) >> 24;
                        ++denom;
                    }
                }
                for (int c = 0; c < 4; ++c) {
                    rgba[c] /= denom;
                }
                int uvIndex = j*pixmaps.planes()[1].width() + i;
                yuvPixels[1][uvIndex] = SkToU8(sk_float_round2int(
                        m[5]*rgba[0] + m[6]*rgba[1] + m[7]*rgba[2] + m[8]*rgba[3] + 255*m[9]));
                yuvPixels[2][uvIndex] = SkToU8(sk_float_round2int(
                        m[10]*rgba[0] + m[11]*rgba[1] + m[12]*rgba[2] + m[13]*rgba[3] + 255*m[14]));
            }
        }
        return sk_gpu_test::LazyYUVImage::Make(std::move(pixmaps));
    }

    sk_sp<SkImage> makeYUVAImage(GrDirectContext* context) {
        return fLazyYUVImage->refImage(context, sk_gpu_test::LazyYUVImage::Type::kFromTextures);
    }

    sk_sp<SkImage> createReferenceImage(GrDirectContext* dContext) {
        auto planarImage = this->makeYUVAImage(dContext);
        if (!planarImage) {
            return nullptr;
        }

        auto resultInfo = SkImageInfo::Make(fLazyYUVImage->dimensions(),
                                            kRGBA_8888_SkColorType,
                                            kPremul_SkAlphaType);
        auto resultSurface = SkSurface::MakeRenderTarget(dContext,
                                                         SkBudgeted::kYes,
                                                         resultInfo,
                                                         1,
                                                         kTopLeft_GrSurfaceOrigin,
                                                         nullptr);
        if (!resultSurface) {
            return nullptr;
        }

        resultSurface->getCanvas()->drawImage(std::move(planarImage), 0, 0);
        return resultSurface->makeImageSnapshot();
    }

    DrawResult onGpuSetup(GrDirectContext* context, SkString* errorMsg) override {
        if (!context || context->abandoned()) {
            return DrawResult::kSkip;
        }

        if (!fLazyYUVImage) {
            fLazyYUVImage = CreatePlanes("images/mandrill_32.png");
        }

        // We make a version of this image for each draw because, if any draw flattens it to
        // RGBA, then all subsequent draws would use the RGBA texture.
        for (int i = 0; i < kNumImages; ++i) {
            fYUVAImages[i] = this->makeYUVAImage(context);
            if (!fYUVAImages[i]) {
                *errorMsg = "Couldn't create src YUVA image.";
                return DrawResult::kFail;
            }
        }

        fReferenceImage = this->createReferenceImage(context);
        if (!fReferenceImage) {
            *errorMsg = "Couldn't create reference YUVA image.";
            return DrawResult::kFail;
        }

        // Some backends (e.g., Vulkan) require all work be completed for backend textures
        // before they are deleted. Since we don't know when we'll next have access to a
        // direct context, flush all the work now.
        context->flush();
        context->submit(true);

        return DrawResult::kOk;
    }

    void onGpuTeardown() override {
        for (sk_sp<SkImage>& image : fYUVAImages) {
            image.reset();
        }
        fReferenceImage.reset();
    }

    SkImage* getYUVAImage(int index) {
        SkASSERT(index >= 0 && index < kNumImages);
        return fYUVAImages[index].get();
    }

    void onDraw(GrRecordingContext*, GrRenderTargetContext*, SkCanvas* canvas) override {
        auto draw_image = [canvas](SkImage* image, SkFilterQuality fq) -> SkSize {
            if (!image) {
                return {0, 0};
            }
            SkPaint paint;
            paint.setFilterQuality(fq);
            canvas->drawImage(image, 0, 0, &paint);
            return {SkIntToScalar(image->width()), SkIntToScalar(image->height())};
        };

        auto draw_image_rect = [canvas](SkImage* image, SkFilterQuality fq) -> SkSize {
            if (!image) {
                return {0, 0};
            }
            SkPaint paint;
            paint.setFilterQuality(fq);
            auto subset = SkRect::Make(image->dimensions());
            subset.inset(subset.width() * .05f, subset.height() * .1f);
            auto dst = SkRect::MakeWH(subset.width(), subset.height());
            canvas->drawImageRect(image, subset, dst, &paint);
            return {dst.width(), dst.height()};
        };

        auto draw_image_shader = [canvas](SkImage* image, SkFilterQuality fq) -> SkSize {
            if (!image) {
                return {0, 0};
            }
            SkMatrix m;
            m.setRotate(45, image->width()/2.f, image->height()/2.f);
            auto shader = image->makeShader(SkTileMode::kMirror, SkTileMode::kDecal, m);
            SkPaint paint;
            paint.setFilterQuality(fq);
            paint.setShader(std::move(shader));
            auto rect = SkRect::MakeWH(image->width() * 1.3f, image->height());
            canvas->drawRect(rect, paint);
            return {rect.width(), rect.height()};
        };

        canvas->translate(kPad, kPad);
        int imageIndex = 0;
        using DrawSig = SkSize(SkImage* image, SkFilterQuality fq);
        using DF = std::function<DrawSig>;
        for (const auto& draw : {DF(draw_image), DF(draw_image_rect), DF(draw_image_shader)}) {
            for (auto scale : {1.f, 4.f, 0.75f}) {
                SkScalar h = 0;
                canvas->save();
                for (auto fq : {kNone_SkFilterQuality, kLow_SkFilterQuality,
                                kMedium_SkFilterQuality, kHigh_SkFilterQuality}) {
                    canvas->save();
                        canvas->scale(scale, scale);
                        auto s1 = draw(this->getYUVAImage(imageIndex++), fq);
                    canvas->restore();
                    canvas->translate(kPad + SkScalarCeilToScalar(scale*s1.width()), 0);
                    canvas->save();
                        canvas->scale(scale, scale);
                        auto s2 = draw(fReferenceImage.get(), fq);
                    canvas->restore();
                    canvas->translate(kPad + SkScalarCeilToScalar(scale*s2.width()), 0);
                    h = std::max({h, s1.height(), s2.height()});
                }
                canvas->restore();
                canvas->translate(0, kPad + SkScalarCeilToScalar(scale*h));
            }
        }
     }

private:
    std::unique_ptr<sk_gpu_test::LazyYUVImage> fLazyYUVImage;

    // 3 draws x 3 scales x 4 filter qualities
    static constexpr int kNumImages = 3 * 3 * 4;
    sk_sp<SkImage> fYUVAImages[kNumImages];
    sk_sp<SkImage> fReferenceImage;

    static constexpr SkScalar kPad = 10.0f;

    using INHERITED = GM;
};

DEF_GM(return new ImageFromYUVTextures;)
}  // namespace skiagm
