blob: 186059444c40472bf594c3eff5cf2a46edc54945 [file] [log] [blame]
/*
* 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);
}