/*
 * Copyright 2023 Google LLC
 *
 * 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"

#ifdef SK_USE_DRAWING_MIPMAP_DOWNSAMPLER

#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkScalar.h"
#include "src/core/SkDraw.h"
#include "src/core/SkMipmap.h"
#include "src/core/SkRasterClip.h"
#include <memory>

namespace {

struct DrawDownSampler : SkMipmapDownSampler {
    SkPaint fPaint;

    DrawDownSampler() {
        // For efficiency, we want to be in src mode when building levels
        // to avoid any extra trying to "blend".
        fPaint.setBlendMode(SkBlendMode::kSrc);
    }

    void buildLevel(const SkPixmap& dst, const SkPixmap& src) override;
};

static SkSamplingOptions choose_options(const SkPixmap& dst, const SkPixmap& src) {
    // if we're a perfect 2x2 downscale, just use bilerp
    if (dst.width() * 2 == src.width() && dst.height() * 2 == src.height()) {
        return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
    }
    // general case -- might experiment with different cubic parameter values
    const auto cubic = SkCubicResampler::CatmullRom();
    return SkSamplingOptions(cubic);
}

void DrawDownSampler::buildLevel(const SkPixmap& dst, const SkPixmap& src) {
    const SkRasterClip rclip(dst.bounds());
    const SkMatrix mx = SkMatrix::Scale(SkIntToScalar(dst.width())  / src.width(),
                                        SkIntToScalar(dst.height()) / src.height());
    const auto sampling = choose_options(dst, src);

    SkDraw draw;
    draw.fDst = dst;
    draw.fCTM = &mx;
    draw.fRC = &rclip;

    SkBitmap bitmap;
    bitmap.installPixels(src.info(), const_cast<void*>(src.addr()), src.rowBytes());

    draw.drawBitmap(bitmap, SkMatrix::I(), nullptr, sampling, fPaint);
}

} // namespace

std::unique_ptr<SkMipmapDownSampler> SkMipmap::MakeDownSampler(const SkPixmap& root) {
    return std::make_unique<DrawDownSampler>();
}

#endif
