blob: 3d88b9d91b34c009e2cccf5cfa6f5e54d5db4eef [file] [log] [blame] [edit]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "flutter/fml/macros.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkCanvasVirtualEnforcer.h"
#include "third_party/skia/include/utils/SkNWayCanvas.h"
#include "third_party/skia/include/utils/SkNoDrawCanvas.h"
#ifndef FLUTTER_SHELL_COMMON_CANVAS_SPY_H_
#define FLUTTER_SHELL_COMMON_CANVAS_SPY_H_
namespace flutter {
class DidDrawCanvas;
//------------------------------------------------------------------------------
/// Facilitates spying on drawing commands to an SkCanvas.
///
/// This is used to determine whether anything was drawn into
/// a canvas so it is possible to implement optimizations that
/// are specific to empty canvases.
class CanvasSpy {
public:
CanvasSpy(SkCanvas* target_canvas);
//----------------------------------------------------------------------------
/// @brief Returns true if any non transparent content has been drawn
/// into
/// the spying canvas. Note that this class does tries to detect
/// empty canvases but in some cases may return true even for
/// empty canvases (e.g when a transparent image is drawn into the
/// canvas).
bool DidDrawIntoCanvas();
//----------------------------------------------------------------------------
/// @brief The returned canvas delegate all operations to the target
/// canvas
/// while spying on them.
SkCanvas* GetSpyingCanvas();
private:
std::unique_ptr<SkNWayCanvas> n_way_canvas_;
std::unique_ptr<DidDrawCanvas> did_draw_canvas_;
FML_DISALLOW_COPY_AND_ASSIGN(CanvasSpy);
};
class DidDrawCanvas final : public SkCanvasVirtualEnforcer<SkNoDrawCanvas> {
public:
DidDrawCanvas(int width, int height);
~DidDrawCanvas() override;
bool DidDrawIntoCanvas();
private:
bool did_draw_ = false;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void willSave() override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
bool onDoSaveBehind(const SkRect*) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void willRestore() override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void didConcat44(const SkM44&) override;
void didScale(SkScalar, SkScalar) override;
void didTranslate(SkScalar, SkScalar) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
virtual void onDrawTextBlob(const SkTextBlob* blob,
SkScalar x,
SkScalar y,
const SkPaint& paint) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
virtual void onDrawPatch(const SkPoint cubics[12],
const SkColor colors[4],
const SkPoint texCoords[4],
SkBlendMode,
const SkPaint& paint) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawPaint(const SkPaint&) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawBehind(const SkPaint&) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawPoints(PointMode,
size_t count,
const SkPoint pts[],
const SkPaint&) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawRect(const SkRect&, const SkPaint&) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawRegion(const SkRegion&, const SkPaint&) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawOval(const SkRect&, const SkPaint&) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawArc(const SkRect&,
SkScalar,
SkScalar,
bool,
const SkPaint&) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawRRect(const SkRRect&, const SkPaint&) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawPath(const SkPath&, const SkPaint&) override;
#ifdef SK_SUPPORT_LEGACY_ONDRAWIMAGERECT
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawImage(const SkImage*,
SkScalar left,
SkScalar top,
const SkPaint*) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawImageRect(const SkImage*,
const SkRect* src,
const SkRect& dst,
const SkPaint*,
SrcRectConstraint) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawImageLattice(const SkImage*,
const Lattice&,
const SkRect&,
const SkPaint*) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawAtlas(const SkImage*,
const SkRSXform[],
const SkRect[],
const SkColor[],
int,
SkBlendMode,
const SkRect*,
const SkPaint*) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawEdgeAAImageSet(const ImageSetEntry[],
int count,
const SkPoint[],
const SkMatrix[],
const SkPaint*,
SrcRectConstraint) override;
#endif
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawImage2(const SkImage*,
SkScalar left,
SkScalar top,
const SkSamplingOptions&,
const SkPaint*) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawImageRect2(const SkImage*,
const SkRect& src,
const SkRect& dst,
const SkSamplingOptions&,
const SkPaint*,
SrcRectConstraint) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawImageLattice2(const SkImage*,
const Lattice&,
const SkRect&,
SkFilterMode,
const SkPaint*) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawVerticesObject(const SkVertices*,
SkBlendMode,
const SkPaint&) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawAtlas2(const SkImage*,
const SkRSXform[],
const SkRect[],
const SkColor[],
int,
SkBlendMode,
const SkSamplingOptions&,
const SkRect*,
const SkPaint*) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onClipRegion(const SkRegion&, SkClipOp) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawPicture(const SkPicture*,
const SkMatrix*,
const SkPaint*) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawEdgeAAQuad(const SkRect&,
const SkPoint[4],
SkCanvas::QuadAAFlags,
const SkColor4f&,
SkBlendMode) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onDrawEdgeAAImageSet2(const ImageSetEntry[],
int count,
const SkPoint[],
const SkMatrix[],
const SkSamplingOptions&,
const SkPaint*,
SrcRectConstraint) override;
// |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
void onFlush() override;
void MarkDrawIfNonTransparentPaint(const SkPaint& paint);
FML_DISALLOW_COPY_AND_ASSIGN(DidDrawCanvas);
};
} // namespace flutter
#endif // FLUTTER_SHELL_COMMON_SKIA_EVENT_TRACER_IMPL_H_