Implement computeFastBounds in SkLocalMatrixImageFilter
This also adds a GM based on Jim's fiddle: https://fiddle.skia.org/c/781234e35c208ee03f79b90613117b91 I confirmed that it never flickers when animating in viewer. Patchset 1 shows the GM being blank (with the computeFastBounds fix disabled). Patchset 3 shows that with the fix enabled, the GM is not blank. Bug: skia:9282 Change-Id: I206f7150c395b0a35ecf0455e4905f72ae057e6b Reviewed-on: https://skia-review.googlesource.com/c/skia/+/295558 Commit-Queue: Michael Ludwig <michaelludwig@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
4598fa1b1a
commit
1c07aa7d8d
@ -25,7 +25,9 @@
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/effects/SkGradientShader.h"
|
||||
#include "include/effects/SkImageFilters.h"
|
||||
#include "tools/Resources.h"
|
||||
#include "tools/ToolUtils.h"
|
||||
#include "tools/timer/TimeUtils.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
@ -161,3 +163,56 @@ DEF_SIMPLE_GM(rotate_imagefilter, canvas, 500, 500) {
|
||||
canvas->translate(0, 150);
|
||||
}
|
||||
}
|
||||
|
||||
class ImageFilterMatrixWLocalMatrix : public skiagm::GM {
|
||||
public:
|
||||
|
||||
// Start at 132 degrees, since that resulted in a skipped draw before the fix to
|
||||
// SkLocalMatrixImageFilter's computeFastBounds() function.
|
||||
ImageFilterMatrixWLocalMatrix() : fDegrees(132.f) {}
|
||||
|
||||
protected:
|
||||
SkString onShortName() override {
|
||||
return SkString("imagefilter_matrix_localmatrix");
|
||||
}
|
||||
|
||||
SkISize onISize() override {
|
||||
return SkISize::Make(512, 512);
|
||||
}
|
||||
|
||||
bool onAnimate(double nanos) override {
|
||||
// Animate the rotation angle to ensure the local matrix bounds modifications work
|
||||
// for a variety of transformations.
|
||||
fDegrees = TimeUtils::Scaled(1e-9f * nanos, 360.f);
|
||||
return true;
|
||||
}
|
||||
|
||||
void onOnceBeforeDraw() override {
|
||||
fImage = GetResourceAsImage("images/mandrill_256.png");
|
||||
}
|
||||
|
||||
void onDraw(SkCanvas* canvas) override {
|
||||
SkMatrix localMatrix;
|
||||
localMatrix.preTranslate(128, 128);
|
||||
localMatrix.preScale(2.0f, 2.0f);
|
||||
|
||||
// This matrix applies a rotate around the center of the image (prior to the simulated
|
||||
// hi-dpi 2x device scale).
|
||||
SkMatrix filterMatrix;
|
||||
filterMatrix.setRotate(fDegrees, 64, 64);
|
||||
|
||||
sk_sp<SkImageFilter> filter =
|
||||
SkImageFilter::MakeMatrixFilter(filterMatrix, kLow_SkFilterQuality, nullptr)
|
||||
->makeWithLocalMatrix(localMatrix);
|
||||
|
||||
SkPaint p;
|
||||
p.setImageFilter(filter);
|
||||
canvas->drawImage(fImage.get(), 128, 128, &p);
|
||||
}
|
||||
|
||||
private:
|
||||
SkScalar fDegrees;
|
||||
sk_sp<SkImage> fImage;
|
||||
};
|
||||
|
||||
DEF_GM(return new ImageFilterMatrixWLocalMatrix();)
|
||||
|
@ -53,3 +53,15 @@ SkIRect SkLocalMatrixImageFilter::onFilterBounds(const SkIRect& src, const SkMat
|
||||
MapDirection dir, const SkIRect* inputRect) const {
|
||||
return this->getInput(0)->filterBounds(src, SkMatrix::Concat(ctm, fLocalM), dir, inputRect);
|
||||
}
|
||||
|
||||
SkRect SkLocalMatrixImageFilter::computeFastBounds(const SkRect& bounds) const {
|
||||
// In order to match the behavior of onFilterBounds, we map 'bounds' by the inverse of our
|
||||
// local matrix, pass that to our child, and then map the result by our local matrix.
|
||||
SkMatrix localInv;
|
||||
if (!fLocalM.invert(&localInv)) {
|
||||
return this->getInput(0)->computeFastBounds(bounds);
|
||||
}
|
||||
|
||||
SkRect localBounds = localInv.mapRect(bounds);
|
||||
return fLocalM.mapRect(this->getInput(0)->computeFastBounds(localBounds));
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ class SkLocalMatrixImageFilter : public SkImageFilter_Base {
|
||||
public:
|
||||
static sk_sp<SkImageFilter> Make(const SkMatrix& localM, sk_sp<SkImageFilter> input);
|
||||
|
||||
SkRect computeFastBounds(const SkRect&) const override;
|
||||
|
||||
protected:
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
sk_sp<SkSpecialImage> onFilterImage(const Context&, SkIPoint* offset) const override;
|
||||
|
Loading…
Reference in New Issue
Block a user