skia2/tools/debugger/DrawCommand.h
Michael Ludwig cfd204a785 Rename/simplify SkCanvas::resetClip() and make recordable
AndroidFramework uses both their own custom display list (which could
handle resetClip with android-side changes) AND conventional picture
recording. In order for replace op emulation to work when they have
been recorded into a picture, we need to make it virtual and supported
in SkPicture.

This also renames the API to ResetClip() from ReplaceClip() and does not
have any additional arguments. Based on AF's usage pattern, it only n
needs to reset the clip to the surface bounds or the device clip
restriction, it seems best to reduce the API as much as possible before
it's adopted.

Bug: skia:10209
Change-Id: I37adb097c84a642f4254b8c0f9d4c7fea8d9abdf
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/430897
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Derek Sollenberger <djsollen@google.com>
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
2021-07-23 19:05:42 +00:00

731 lines
22 KiB
C++

/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SKDRAWCOMMAND_H_
#define SKDRAWCOMMAND_H_
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkFlattenable.h"
#include "include/core/SkPath.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRSXform.h"
#include "include/core/SkRegion.h"
#include "include/core/SkString.h"
#include "include/core/SkVertices.h"
#include "include/private/SkTDArray.h"
#include "src/core/SkDrawShadowInfo.h"
#include "src/core/SkTLazy.h"
#include "src/utils/SkJSONWriter.h"
#include "tools/UrlDataManager.h"
class DebugLayerManager;
class DrawCommand {
public:
enum OpType {
kBeginDrawPicture_OpType,
kClear_OpType,
kClipPath_OpType,
kClipRegion_OpType,
kClipRect_OpType,
kClipRRect_OpType,
kClipShader_OpType,
kResetClip_OpType,
kConcat_OpType,
kConcat44_OpType,
kDrawAnnotation_OpType,
kDrawBitmap_OpType,
kDrawBitmapRect_OpType,
kDrawDRRect_OpType,
kDrawImage_OpType,
kDrawImageLattice_OpType,
kDrawImageRect_OpType,
kDrawImageRectLayer_OpType, // unique to DebugCanvas
kDrawOval_OpType,
kDrawArc_OpType,
kDrawPaint_OpType,
kDrawPatch_OpType,
kDrawPath_OpType,
kDrawPoints_OpType,
kDrawRect_OpType,
kDrawRRect_OpType,
kDrawRegion_OpType,
kDrawShadow_OpType,
kDrawTextBlob_OpType,
kDrawVertices_OpType,
kDrawAtlas_OpType,
kDrawDrawable_OpType,
kDrawEdgeAAQuad_OpType,
kDrawEdgeAAImageSet_OpType,
kEndDrawPicture_OpType,
kRestore_OpType,
kSave_OpType,
kSaveLayer_OpType,
kSetMatrix_OpType,
kSetM44_OpType,
kLast_OpType = kSetM44_OpType
};
static const int kOpTypeCount = kLast_OpType + 1;
static void WritePNG(SkBitmap bitmap, SkWStream& out);
DrawCommand(OpType opType);
virtual ~DrawCommand() {}
bool isVisible() const { return fVisible; }
void setVisible(bool toggle) { fVisible = toggle; }
virtual void execute(SkCanvas*) const = 0;
virtual bool render(SkCanvas* canvas) const { return false; }
virtual void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const;
static const char* GetCommandString(OpType type);
// Helper methods for converting things to JSON
static void MakeJsonColor(SkJSONWriter&, const SkColor color);
static void MakeJsonColor4f(SkJSONWriter&, const SkColor4f& color);
static void MakeJsonPoint(SkJSONWriter&, const SkPoint& point);
static void MakeJsonPoint(SkJSONWriter&, SkScalar x, SkScalar y);
static void MakeJsonPoint3(SkJSONWriter&, const SkPoint3& point);
static void MakeJsonRect(SkJSONWriter&, const SkRect& rect);
static void MakeJsonIRect(SkJSONWriter&, const SkIRect&);
static void MakeJsonMatrix(SkJSONWriter&, const SkMatrix&);
static void MakeJsonMatrix44(SkJSONWriter&, const SkM44&);
static void MakeJsonPath(SkJSONWriter&, const SkPath& path);
static void MakeJsonRegion(SkJSONWriter&, const SkRegion& region);
static void MakeJsonPaint(SkJSONWriter&, const SkPaint& paint, UrlDataManager& urlDataManager);
static void MakeJsonLattice(SkJSONWriter&, const SkCanvas::Lattice& lattice);
static void flatten(const SkFlattenable* flattenable,
SkJSONWriter& writer,
UrlDataManager& urlDataManager);
static bool flatten(const SkImage& image, SkJSONWriter& writer, UrlDataManager& urlDataManager);
static bool flatten(const SkBitmap& bitmap,
SkJSONWriter& writer,
UrlDataManager& urlDataManager);
OpType getOpType() const { return fOpType; }
private:
OpType fOpType;
bool fVisible;
};
class RestoreCommand : public DrawCommand {
public:
RestoreCommand();
void execute(SkCanvas* canvas) const override;
private:
using INHERITED = DrawCommand;
};
class ClearCommand : public DrawCommand {
public:
ClearCommand(SkColor color);
void execute(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkColor fColor;
using INHERITED = DrawCommand;
};
class ClipPathCommand : public DrawCommand {
public:
ClipPathCommand(const SkPath& path, SkClipOp op, bool doAA);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkPath fPath;
SkClipOp fOp;
bool fDoAA;
using INHERITED = DrawCommand;
};
class ClipRegionCommand : public DrawCommand {
public:
ClipRegionCommand(const SkRegion& region, SkClipOp op);
void execute(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkRegion fRegion;
SkClipOp fOp;
using INHERITED = DrawCommand;
};
class ClipRectCommand : public DrawCommand {
public:
ClipRectCommand(const SkRect& rect, SkClipOp op, bool doAA);
void execute(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkRect fRect;
SkClipOp fOp;
bool fDoAA;
using INHERITED = DrawCommand;
};
class ClipRRectCommand : public DrawCommand {
public:
ClipRRectCommand(const SkRRect& rrect, SkClipOp op, bool doAA);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkRRect fRRect;
SkClipOp fOp;
bool fDoAA;
using INHERITED = DrawCommand;
};
class ClipShaderCommand : public DrawCommand {
public:
ClipShaderCommand(sk_sp<SkShader>, SkClipOp);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
sk_sp<SkShader> fShader;
SkClipOp fOp;
using INHERITED = DrawCommand;
};
class ResetClipCommand : public DrawCommand {
public:
ResetClipCommand();
void execute(SkCanvas* canvas) const override;
private:
using INHERITED = DrawCommand;
};
class ConcatCommand : public DrawCommand {
public:
ConcatCommand(const SkMatrix& matrix);
void execute(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkMatrix fMatrix;
using INHERITED = DrawCommand;
};
class Concat44Command : public DrawCommand {
public:
Concat44Command(const SkM44& matrix);
void execute(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkM44 fMatrix;
using INHERITED = DrawCommand;
};
class DrawAnnotationCommand : public DrawCommand {
public:
DrawAnnotationCommand(const SkRect&, const char key[], sk_sp<SkData> value);
void execute(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkRect fRect;
SkString fKey;
sk_sp<SkData> fValue;
using INHERITED = DrawCommand;
};
class DrawImageCommand : public DrawCommand {
public:
DrawImageCommand(const SkImage* image, SkScalar left, SkScalar top,
const SkSamplingOptions&, const SkPaint* paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
uint64_t imageId(UrlDataManager& udb) const;
private:
sk_sp<const SkImage> fImage;
SkScalar fLeft;
SkScalar fTop;
SkSamplingOptions fSampling;
SkTLazy<SkPaint> fPaint;
using INHERITED = DrawCommand;
};
class DrawImageLatticeCommand : public DrawCommand {
public:
DrawImageLatticeCommand(const SkImage* image,
const SkCanvas::Lattice& lattice,
const SkRect& dst,
SkFilterMode,
const SkPaint* paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
uint64_t imageId(UrlDataManager& udb) const;
private:
sk_sp<const SkImage> fImage;
SkCanvas::Lattice fLattice;
SkRect fDst;
SkFilterMode fFilter;
SkTLazy<SkPaint> fPaint;
using INHERITED = DrawCommand;
};
class DrawImageRectCommand : public DrawCommand {
public:
DrawImageRectCommand(const SkImage* image,
const SkRect& src,
const SkRect& dst,
const SkSamplingOptions& sampling,
const SkPaint* paint,
SkCanvas::SrcRectConstraint constraint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
uint64_t imageId(UrlDataManager& udm) const;
private:
sk_sp<const SkImage> fImage;
SkRect fSrc;
SkRect fDst;
SkSamplingOptions fSampling;
SkTLazy<SkPaint> fPaint;
SkCanvas::SrcRectConstraint fConstraint;
using INHERITED = DrawCommand;
};
// Command for resolving the deferred SkImage representing an android layer
// Functions like DrawImageRect except it uses the saved UrlDataManager to resolve the image
// at the time execute() is called.
class DrawImageRectLayerCommand : public DrawCommand {
public:
DrawImageRectLayerCommand(DebugLayerManager* layerManager,
const int nodeId,
const int frame,
const SkRect& src,
const SkRect& dst,
const SkSamplingOptions& sampling,
const SkPaint* paint,
SkCanvas::SrcRectConstraint constraint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
DebugLayerManager* fLayerManager;
int fNodeId;
int fFrame;
SkRect fSrc;
SkRect fDst;
SkSamplingOptions fSampling;
SkTLazy<SkPaint> fPaint;
SkCanvas::SrcRectConstraint fConstraint;
using INHERITED = DrawCommand;
};
class DrawOvalCommand : public DrawCommand {
public:
DrawOvalCommand(const SkRect& oval, const SkPaint& paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkRect fOval;
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class DrawArcCommand : public DrawCommand {
public:
DrawArcCommand(const SkRect& oval,
SkScalar startAngle,
SkScalar sweepAngle,
bool useCenter,
const SkPaint& paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkRect fOval;
SkScalar fStartAngle;
SkScalar fSweepAngle;
bool fUseCenter;
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class DrawPaintCommand : public DrawCommand {
public:
DrawPaintCommand(const SkPaint& paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class DrawBehindCommand : public DrawCommand {
public:
DrawBehindCommand(const SkPaint& paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class DrawPathCommand : public DrawCommand {
public:
DrawPathCommand(const SkPath& path, const SkPaint& paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkPath fPath;
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class BeginDrawPictureCommand : public DrawCommand {
public:
BeginDrawPictureCommand(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
private:
sk_sp<const SkPicture> fPicture;
SkTLazy<SkMatrix> fMatrix;
SkTLazy<SkPaint> fPaint;
using INHERITED = DrawCommand;
};
class EndDrawPictureCommand : public DrawCommand {
public:
EndDrawPictureCommand(bool restore);
void execute(SkCanvas* canvas) const override;
private:
bool fRestore;
using INHERITED = DrawCommand;
};
class DrawPointsCommand : public DrawCommand {
public:
DrawPointsCommand(SkCanvas::PointMode mode,
size_t count,
const SkPoint pts[],
const SkPaint& paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkCanvas::PointMode fMode;
SkTDArray<SkPoint> fPts;
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class DrawRegionCommand : public DrawCommand {
public:
DrawRegionCommand(const SkRegion& region, const SkPaint& paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkRegion fRegion;
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class DrawTextBlobCommand : public DrawCommand {
public:
DrawTextBlobCommand(sk_sp<SkTextBlob> blob, SkScalar x, SkScalar y, const SkPaint& paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
sk_sp<SkTextBlob> fBlob;
SkScalar fXPos;
SkScalar fYPos;
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class DrawPatchCommand : public DrawCommand {
public:
DrawPatchCommand(const SkPoint cubics[12],
const SkColor colors[4],
const SkPoint texCoords[4],
SkBlendMode bmode,
const SkPaint& paint);
void execute(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkPoint fCubics[12];
SkColor* fColorsPtr;
SkColor fColors[4];
SkPoint* fTexCoordsPtr;
SkPoint fTexCoords[4];
SkBlendMode fBlendMode;
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class DrawRectCommand : public DrawCommand {
public:
DrawRectCommand(const SkRect& rect, const SkPaint& paint);
void execute(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkRect fRect;
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class DrawRRectCommand : public DrawCommand {
public:
DrawRRectCommand(const SkRRect& rrect, const SkPaint& paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkRRect fRRect;
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class DrawDRRectCommand : public DrawCommand {
public:
DrawDRRectCommand(const SkRRect& outer, const SkRRect& inner, const SkPaint& paint);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkRRect fOuter;
SkRRect fInner;
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class DrawVerticesCommand : public DrawCommand {
public:
DrawVerticesCommand(sk_sp<SkVertices>, SkBlendMode, const SkPaint&);
void execute(SkCanvas* canvas) const override;
private:
sk_sp<SkVertices> fVertices;
SkBlendMode fBlendMode;
SkPaint fPaint;
using INHERITED = DrawCommand;
};
class DrawAtlasCommand : public DrawCommand {
public:
DrawAtlasCommand(const SkImage*,
const SkRSXform[],
const SkRect[],
const SkColor[],
int,
SkBlendMode,
const SkSamplingOptions&,
const SkRect*,
const SkPaint*);
void execute(SkCanvas* canvas) const override;
private:
sk_sp<const SkImage> fImage;
SkTDArray<SkRSXform> fXform;
SkTDArray<SkRect> fTex;
SkTDArray<SkColor> fColors;
SkBlendMode fBlendMode;
SkSamplingOptions fSampling;
SkTLazy<SkRect> fCull;
SkTLazy<SkPaint> fPaint;
using INHERITED = DrawCommand;
};
class SaveCommand : public DrawCommand {
public:
SaveCommand();
void execute(SkCanvas* canvas) const override;
private:
using INHERITED = DrawCommand;
};
class SaveLayerCommand : public DrawCommand {
public:
SaveLayerCommand(const SkCanvas::SaveLayerRec&);
void execute(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkTLazy<SkRect> fBounds;
SkTLazy<SkPaint> fPaint;
sk_sp<const SkImageFilter> fBackdrop;
uint32_t fSaveLayerFlags;
using INHERITED = DrawCommand;
};
class SetMatrixCommand : public DrawCommand {
public:
SetMatrixCommand(const SkMatrix& matrix);
void execute(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkMatrix fMatrix;
using INHERITED = DrawCommand;
};
class SetM44Command : public DrawCommand {
public:
SetM44Command(const SkM44& matrix);
void execute(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkM44 fMatrix;
using INHERITED = DrawCommand;
};
class DrawShadowCommand : public DrawCommand {
public:
DrawShadowCommand(const SkPath& path, const SkDrawShadowRec& rec);
void execute(SkCanvas* canvas) const override;
bool render(SkCanvas* canvas) const override;
void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
private:
SkPath fPath;
SkDrawShadowRec fShadowRec;
using INHERITED = DrawCommand;
};
class DrawDrawableCommand : public DrawCommand {
public:
DrawDrawableCommand(SkDrawable*, const SkMatrix*);
void execute(SkCanvas* canvas) const override;
private:
sk_sp<SkDrawable> fDrawable;
SkTLazy<SkMatrix> fMatrix;
using INHERITED = DrawCommand;
};
class DrawEdgeAAQuadCommand : public DrawCommand {
public:
DrawEdgeAAQuadCommand(const SkRect& rect,
const SkPoint clip[4],
SkCanvas::QuadAAFlags aa,
const SkColor4f& color,
SkBlendMode mode);
void execute(SkCanvas* canvas) const override;
private:
SkRect fRect;
SkPoint fClip[4];
int fHasClip;
SkCanvas::QuadAAFlags fAA;
SkColor4f fColor;
SkBlendMode fMode;
using INHERITED = DrawCommand;
};
class DrawEdgeAAImageSetCommand : public DrawCommand {
public:
DrawEdgeAAImageSetCommand(const SkCanvas::ImageSetEntry[],
int count,
const SkPoint[],
const SkMatrix[],
const SkSamplingOptions&,
const SkPaint*,
SkCanvas::SrcRectConstraint);
void execute(SkCanvas* canvas) const override;
private:
SkAutoTArray<SkCanvas::ImageSetEntry> fSet;
int fCount;
SkAutoTArray<SkPoint> fDstClips;
SkAutoTArray<SkMatrix> fPreViewMatrices;
SkSamplingOptions fSampling;
SkTLazy<SkPaint> fPaint;
SkCanvas::SrcRectConstraint fConstraint;
using INHERITED = DrawCommand;
};
#endif