/*
 * 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 "src/core/SkSpecialSurface.h"

#include <memory>

#include "include/core/SkCanvas.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkMallocPixelRef.h"
#include "src/core/SkBitmapDevice.h"
#include "src/core/SkCanvasPriv.h"
#include "src/core/SkDevice.h"
#include "src/core/SkSpecialImage.h"
#include "src/core/SkSurfacePriv.h"

SkSpecialSurface::SkSpecialSurface(sk_sp<SkBaseDevice> device, const SkIRect& subset)
        : fSubset(subset) {
    SkASSERT(fSubset.width() > 0);
    SkASSERT(fSubset.height() > 0);

    fCanvas = std::make_unique<SkCanvas>(std::move(device));
    fCanvas->clipRect(SkRect::Make(subset));
#ifdef SK_IS_BOT
    fCanvas->clear(SK_ColorRED);  // catch any imageFilter sloppiness
#endif
}

sk_sp<SkSpecialImage> SkSpecialSurface::makeImageSnapshot() {
    fCanvas->restoreToCount(0);

    // Because of the above 'restoreToCount(0)' we know we're getting the base device here.
    SkBaseDevice* baseDevice = SkCanvasPriv::TopDevice(fCanvas.get());
    if (!baseDevice) {
        return nullptr;
    }

    sk_sp<SkSpecialImage> image = baseDevice->snapSpecial(this->subset());

    fCanvas.reset();
    return image;
}

///////////////////////////////////////////////////////////////////////////////
sk_sp<SkSpecialSurface> SkSpecialSurface::MakeRaster(const SkImageInfo& info,
                                                     const SkSurfaceProps& props) {
    if (!SkSurfaceValidateRasterInfo(info)) {
        return nullptr;
    }

    sk_sp<SkPixelRef> pr = SkMallocPixelRef::MakeAllocate(info, 0);
    if (!pr) {
        return nullptr;
    }

    SkBitmap bitmap;
    bitmap.setInfo(info, info.minRowBytes());
    bitmap.setPixelRef(std::move(pr), 0, 0);

    sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap,
                                                  { props.flags(), kUnknown_SkPixelGeometry }));
    if (!device) {
        return nullptr;
    }

    const SkIRect subset = SkIRect::MakeSize(info.dimensions());

    return sk_make_sp<SkSpecialSurface>(std::move(device), subset);
}

///////////////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
#include "include/gpu/GrRecordingContext.h"
#include "src/gpu/ganesh/GrColorInfo.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"

sk_sp<SkSpecialSurface> SkSpecialSurface::MakeRenderTarget(GrRecordingContext* rContext,
                                                           const SkImageInfo& ii,
                                                           const SkSurfaceProps& props,
                                                           GrSurfaceOrigin surfaceOrigin) {
    if (!rContext) {
        return nullptr;
    }

    auto device = rContext->priv().createDevice(SkBudgeted::kYes, ii, SkBackingFit::kApprox, 1,
                                                GrMipmapped::kNo, GrProtected::kNo,
                                                surfaceOrigin,
                                                { props.flags(), kUnknown_SkPixelGeometry },
                                                skgpu::v1::Device::InitContents::kUninit);
    if (!device) {
        return nullptr;
    }

    const SkIRect subset = SkIRect::MakeSize(ii.dimensions());

    return sk_make_sp<SkSpecialSurface>(std::move(device), subset);
}

#endif // SK_SUPPORT_GPU

///////////////////////////////////////////////////////////////////////////////
#if SK_GRAPHITE_ENABLED
#include "src/gpu/graphite/Device.h"

sk_sp<SkSpecialSurface> SkSpecialSurface::MakeGraphite(skgpu::graphite::Recorder* recorder,
                                                       const SkImageInfo& ii,
                                                       const SkSurfaceProps& props) {
    using namespace skgpu::graphite;

    if (!recorder) {
        return nullptr;
    }

    sk_sp<Device> device = Device::Make(recorder, ii, SkBudgeted::kYes, Mipmapped::kNo,
                                        { props.flags(), kUnknown_SkPixelGeometry },
                                        /* addInitialClear= */ false);
    if (!device) {
        return nullptr;
    }

    const SkIRect subset = SkIRect::MakeSize(ii.dimensions());

    return sk_make_sp<SkSpecialSurface>(std::move(device), subset);
}

#endif // SK_GRAPHITE_ENABLED
