Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 6cafdc0

Browse files
lhkbobSkia Commit-Bot
authored andcommitted
Revert "Draw image filters directly under non-axis-aligned transforms"
This reverts commit f8f23b2. Reason for revert: b/172617382 is creating issues for Android's Webview Original change's description: > Draw image filters directly under non-axis-aligned transforms > > This removes hacking the canvas CTM and wrapping the paint's image > filter in a special MatrixTransform that computed a post-transform > instead of its documented pre-transform effect. Performance-wise, the > computed layer sizes should be about the same, but we avoid one less > render target switch because we apply the transformation while drawing > to the dst device, vs. transforming into another temporary layer and > then drawing that to the dst device. > > Several important changes in behavior here: > 1. The DeviceCM record no longer has a stashed matrix to restore and > holds its restoration paint directly. > 2. Devices for image filter inputs can now have device-to-global > transforms that are not integer translates. > 3. The MatrixTransform hack punted when there was perspective because it > could produce excessively large temporary images, but the new version > appears to work around that. We now impose a maximum layer size to > protect against that and automatically scale the layer to prevent it. > Perspective image filters otherwise now draw correctly. > 6. Updated layer sizing code to use the new image filter APIs > 7. Updated backdrop filter and restore filters to go through the same > code paths, although restore filters skip the intermediate image > transform. > - layer bounds and transforms now go through the updated skif API > and is hopefully more straight forward to understand. > 8. Now we can optimize root color filter nodes of a filter DAG, even if > the entire DAG can't be represented as a color filter. The last node > is pulled off and composed with the restoration paint instead. > > Bug: skia:9074,skia:9283 > Change-Id: I1fa1d50135b9d6d453b02f89aa3cc3b54deab678 > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/328376 > Commit-Queue: Michael Ludwig <[email protected]> > Reviewed-by: Brian Salomon <[email protected]> [email protected],[email protected],[email protected],[email protected],[email protected] Change-Id: I098d0e4b8ee067b436400eb9fea047e629544eec No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: skia:9074 Bug: skia:9283 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/332737 Reviewed-by: Michael Ludwig <[email protected]> Reviewed-by: Derek Sollenberger <[email protected]> Commit-Queue: Michael Ludwig <[email protected]>
1 parent 05f74f2 commit 6cafdc0

File tree

8 files changed

+498
-462
lines changed

8 files changed

+498
-462
lines changed

RELEASE_NOTES.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ Milestone 88
1212
* Limit the types and intrinsics supported in SkRuntimeEffect to GLSL ES 1.00
1313
https://review.skia.org/332597
1414

15-
* Image filters with perspective, for saveLayer and draws, are now drawn correctly. Performance
16-
and quality is highest if user bounds are provided to saveLayer.
17-
https://review.skia.org/328376
18-
1915
* Add AVIF support to SkHeifCodec.
2016

2117
* Add support for creating SkSurfaceCharacterizations directly for use by a

include/core/SkCanvas.h

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2557,6 +2557,13 @@ class SK_API SkCanvas {
25572557

25582558
virtual void onDiscard();
25592559

2560+
// Clip rectangle bounds. Called internally by saveLayer.
2561+
// returns false if the entire rectangle is entirely clipped out
2562+
// If non-NULL, The imageFilter parameter will be used to expand the clip
2563+
// and offscreen bounds for any margin required by the filter DAG.
2564+
bool clipRectBounds(const SkRect* bounds, SaveLayerFlags flags, SkIRect* intersection,
2565+
const SkImageFilter* imageFilter = nullptr);
2566+
25602567
SkBaseDevice* getTopDevice() const;
25612568

25622569
private:
@@ -2594,10 +2601,17 @@ class SK_API SkCanvas {
25942601
// safely with 32 and 64 bit machines (to ensure the storage is enough)
25952602
intptr_t fStorage[32];
25962603
class SkDrawIter* fImpl; // this points at fStorage
2604+
SkPaint fDefaultPaint;
25972605
SkIPoint fDeviceOrigin;
25982606
bool fDone;
25992607
};
26002608

2609+
static bool BoundsAffectsClip(SaveLayerFlags);
2610+
2611+
static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
2612+
SkBaseDevice* dst, const SkIPoint& dstOrigin,
2613+
const SkMatrix& ctm);
2614+
26012615
enum ShaderOverrideOpacity {
26022616
kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image)
26032617
kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque
@@ -2626,7 +2640,7 @@ class SK_API SkCanvas {
26262640
// the first N recs that can fit here mean we won't call malloc
26272641
static constexpr int kMCRecSize = 128; // most recent measurement
26282642
static constexpr int kMCRecCount = 32; // common depth for save/restores
2629-
static constexpr int kDeviceCMSize = 96; // most recent measurement
2643+
static constexpr int kDeviceCMSize = 64; // most recent measurement
26302644

26312645
intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
26322646
intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)];
@@ -2709,31 +2723,14 @@ class SK_API SkCanvas {
27092723
void internalDrawPaint(const SkPaint& paint);
27102724
void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
27112725
void internalSaveBehind(const SkRect*);
2726+
void internalDrawDevice(SkBaseDevice*, const SkPaint*);
27122727

27132728
void internalConcat44(const SkM44&);
27142729

27152730
// shared by save() and saveLayer()
27162731
void internalSave();
27172732
void internalRestore();
27182733

2719-
enum class DeviceCompatibleWithFilter : bool {
2720-
// Check the src device's local-to-device matrix for compatibility with the filter, and if
2721-
// it is not compatible, introduce an intermediate image and transformation that allows the
2722-
// filter to be evaluated on the modified src content.
2723-
kUnknown = false,
2724-
// Assume that the src device's local-to-device matrix is compatible with the filter.
2725-
kYes = true
2726-
};
2727-
/**
2728-
* Filters the contents of 'src' and draws the result into 'dst'. The filter is evaluated
2729-
* relative to the current canvas matrix, and src is drawn to dst using their relative transform
2730-
* 'paint' is applied after the filter and must not have a mask or image filter of its own.
2731-
* A null 'filter' behaves as if the identity filter were used.
2732-
*/
2733-
void internalDrawDeviceWithFilter(SkBaseDevice* src, SkBaseDevice* dst,
2734-
const SkPaint& paint, const SkImageFilter* filter,
2735-
DeviceCompatibleWithFilter compat);
2736-
27372734
/*
27382735
* Returns true if drawing the specified rect (or all if it is null) with the specified
27392736
* paint (or default if null) would overwrite the entire root device of the canvas

0 commit comments

Comments
 (0)