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

#include "src/capture/SkCaptureCanvas.h"

#include "include/core/SkPicture.h"
#include "include/core/SkRasterHandleAllocator.h"
#include "include/core/SkRefCnt.h"
#include "include/private/base/SkAssert.h"
#include "include/utils/SkNWayCanvas.h"
#include "src/capture/SkCaptureManager.h"
#include "src/core/SkCanvasPriv.h"

SkCaptureCanvas::SkCaptureCanvas(SkCanvas* canvas, SkCaptureManager* manager)
        : SkNWayCanvas(canvas->imageInfo().width(), canvas->imageInfo().height()) {
    fBaseCanvas = canvas;
    fManager = manager;
    this->addCanvas(canvas);
}

SkCaptureCanvas::~SkCaptureCanvas() = default;

void SkCaptureCanvas::pollCapturingStatus() {
    bool shouldPoll = fManager->isCurrentlyCapturing();
    if (fCapturing != shouldPoll) {
        if (shouldPoll) {
            this->attachRecordingCanvas();
        } else {
            this->detachRecordingCanvas();
        }
        fCapturing = shouldPoll;
    }
}

sk_sp<SkPicture> SkCaptureCanvas::snapPicture() {
    if (!fCapturing) {
        return nullptr;
    }
    this->detachRecordingCanvas(); // remove the stale recording canvas before the recorder finishes
    auto skp = fRecorder.finishRecordingAsPicture();
    this->attachRecordingCanvas();
    return skp;
}

void SkCaptureCanvas::attachRecordingCanvas() {
    SkASSERT(this->fList.size() == 1);
    this->addCanvas(fRecorder.beginRecording(fBaseCanvas->imageInfo().width(),
                                              fBaseCanvas->imageInfo().height()));
}

void SkCaptureCanvas::detachRecordingCanvas() {
    SkASSERT(this->fList.size() == 2);
    this->removeCanvas(fRecorder.getRecordingCanvas());
}

void SkCaptureCanvas::onSurfaceDelete() {
    // TODO (b/412351769): signal to the capture manager that this canvas's surface has been deleted
}

//////////////////// Function forwarding ///////////////////////

void SkCaptureCanvas::willSave() {
    this->pollCapturingStatus();
    this->SkNWayCanvas::willSave();
}

SkCanvas::SaveLayerStrategy SkCaptureCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
    this->pollCapturingStatus();
    return this->SkNWayCanvas::getSaveLayerStrategy(rec);
}

bool SkCaptureCanvas::onDoSaveBehind(const SkRect* bounds) {
    this->pollCapturingStatus();
    return this->SkNWayCanvas::onDoSaveBehind(bounds);
}

void SkCaptureCanvas::willRestore() {
    this->pollCapturingStatus();
    this->SkNWayCanvas::willRestore();
}

void SkCaptureCanvas::didConcat44(const SkM44& m) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::didConcat44(m);
}

void SkCaptureCanvas::didSetM44(const SkM44& matrix) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::didSetM44(matrix);
}

void SkCaptureCanvas::didTranslate(SkScalar x, SkScalar y) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::didTranslate(x, y);
}

void SkCaptureCanvas::didScale(SkScalar x, SkScalar y) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::didScale(x, y);
}

void SkCaptureCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onClipRect(rect, op, edgeStyle);
}

void SkCaptureCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onClipRRect(rrect, op, edgeStyle);
}

void SkCaptureCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onClipPath(path, op, edgeStyle);
}

void SkCaptureCanvas::onClipShader(sk_sp<SkShader> sh, SkClipOp op) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onClipShader(sh, op);
}

void SkCaptureCanvas::onClipRegion(const SkRegion& deviceRgn, SkClipOp op) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onClipRegion(deviceRgn, op);
}

void SkCaptureCanvas::onResetClip() {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onResetClip();
}

void SkCaptureCanvas::onDrawPaint(const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawPaint(paint);
}

void SkCaptureCanvas::onDrawBehind(const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawBehind(paint);
}

void SkCaptureCanvas::onDrawPoints(PointMode mode,
                                   size_t count,
                                   const SkPoint pts[],
                                   const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawPoints(mode, count, pts, paint);
}

void SkCaptureCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawRect(rect, paint);
}

void SkCaptureCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawRegion(region, paint);
}

void SkCaptureCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawOval(rect, paint);
}

void SkCaptureCanvas::onDrawArc(const SkRect& rect,
                                SkScalar startAngle,
                                SkScalar sweepAngle,
                                bool useCenter,
                                const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawArc(rect, startAngle, sweepAngle, useCenter, paint);
}

void SkCaptureCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawRRect(rrect, paint);
}

void SkCaptureCanvas::onDrawDRRect(const SkRRect& outer,
                                   const SkRRect& inner,
                                   const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawDRRect(outer, inner, paint);
}

void SkCaptureCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawPath(path, paint);
}

void SkCaptureCanvas::onDrawImage2(const SkImage* image,
                                   SkScalar left,
                                   SkScalar top,
                                   const SkSamplingOptions& sampling,
                                   const SkPaint* paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawImage2(image, left, top, sampling, paint);
}

void SkCaptureCanvas::onDrawImageRect2(const SkImage* image,
                                       const SkRect& src,
                                       const SkRect& dst,
                                       const SkSamplingOptions& sampling,
                                       const SkPaint* paint,
                                       SrcRectConstraint constraint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawImageRect2(image, src, dst, sampling, paint, constraint);
}

void SkCaptureCanvas::onDrawImageLattice2(const SkImage* image,
                                          const Lattice& lattice,
                                          const SkRect& dst,
                                          SkFilterMode filter,
                                          const SkPaint* paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawImageLattice2(image, lattice, dst, filter, paint);
}

void SkCaptureCanvas::onDrawAtlas2(const SkImage* image,
                                   const SkRSXform xform[],
                                   const SkRect tex[],
                                   const SkColor colors[],
                                   int count,
                                   SkBlendMode bmode,
                                   const SkSamplingOptions& sampling,
                                   const SkRect* cull,
                                   const SkPaint* paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawAtlas2(image, xform, tex, colors, count, bmode, sampling, cull, paint);
}

void SkCaptureCanvas::onDrawGlyphRunList(const sktext::GlyphRunList& list, const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawGlyphRunList(list, paint);
}

void SkCaptureCanvas::onDrawTextBlob(const SkTextBlob* blob,
                                     SkScalar x,
                                     SkScalar y,
                                     const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawTextBlob(blob, x, y, paint);
}

void SkCaptureCanvas::onDrawSlug(const sktext::gpu::Slug* slug, const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawSlug(slug, paint);
}

void SkCaptureCanvas::onDrawPicture(const SkPicture* picture,
                                    const SkMatrix* matrix,
                                    const SkPaint* paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawPicture(picture, matrix, paint);
}

void SkCaptureCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawDrawable(drawable, matrix);
}

void SkCaptureCanvas::onDrawVerticesObject(const SkVertices* vertices,
                                           SkBlendMode bmode,
                                           const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawVerticesObject(vertices, bmode, paint);
}

void SkCaptureCanvas::onDrawPatch(const SkPoint cubics[12],
                                  const SkColor colors[4],
                                  const SkPoint texCoords[4],
                                  SkBlendMode bmode,
                                  const SkPaint& paint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawPatch(cubics, colors, texCoords, bmode, paint);
}

void SkCaptureCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawShadowRec(path, rec);
}

void SkCaptureCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* data) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawAnnotation(rect, key, data);
}

void SkCaptureCanvas::onDrawEdgeAAQuad(const SkRect& rect,
                                       const SkPoint clip[4],
                                       QuadAAFlags aa,
                                       const SkColor4f& color,
                                       SkBlendMode mode) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawEdgeAAQuad(rect, clip, aa, color, mode);
}

void SkCaptureCanvas::onDrawEdgeAAImageSet2(const ImageSetEntry set[],
                                            int count,
                                            const SkPoint dstClips[],
                                            const SkMatrix preViewMatrices[],
                                            const SkSamplingOptions& sampling,
                                            const SkPaint* paint,
                                            SrcRectConstraint constraint) {
    this->pollCapturingStatus();
    this->SkNWayCanvas::onDrawEdgeAAImageSet2(
            set, count, dstClips, preViewMatrices, sampling, paint, constraint);
}
