27dddae313
This reverts commit32a4910e57
. Reason for revert: SkMatrix::toString use has been removed from flutter and has been picked up in fuchsia Additionally some bookmaker changes take into account recent additions of typedef comments and the generated header comment. Original change's description: > Revert "remove toString" > > This reverts commit5191880cbf
. > > Reason for revert: broke flutter > > Original change's description: > > remove toString > > > > toString may have been used by obsolete debugger only > > find out if that is so > > > > R=​brianosman@google.com,bsalomon@google.com > > > > Docs-Preview: https://skia.org/?cl=119894 > > Bug:830651 > > Change-Id: I737f19b7d3fbc869bea2f443fa3b5ed7c1393ffd > > Reviewed-on: https://skia-review.googlesource.com/119894 > > Commit-Queue: Cary Clark <caryclark@google.com> > > Reviewed-by: Brian Salomon <bsalomon@google.com> > > TBR=bsalomon@google.com,brianosman@google.com,caryclark@google.com,caryclark@skia.org > > Change-Id: I9f81de6c3615ee0608bcea9081b77239b4b8816c TBR=bsalomon@google.com,brianosman@google.com # Not skipping CQ checks because original CL landed > 1 day ago. Reviewed-on: https://skia-review.googlesource.com/129623 Reviewed-by: Cary Clark <caryclark@skia.org> Commit-Queue: Cary Clark <caryclark@google.com> Docs-Preview: https://skia.org/?cl=133583 Bug: 830651 Change-Id: If8499e796be63580ad419e150e94d43e8b89de1b Reviewed-on: https://skia-review.googlesource.com/133583 Commit-Queue: Cary Clark <caryclark@skia.org> Auto-Submit: Cary Clark <caryclark@skia.org>
200 lines
7.3 KiB
C++
200 lines
7.3 KiB
C++
/*
|
|
* Copyright 2011 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "SkArenaAlloc.h"
|
|
#include "SkBitmap.h"
|
|
#include "SkCanvas.h"
|
|
#include "SkColorSpaceXformer.h"
|
|
#include "SkDrawLooper.h"
|
|
#include "SkFlattenablePriv.h"
|
|
#include "SkLightingImageFilter.h"
|
|
#include "SkPoint3.h"
|
|
#include "SkTypes.h"
|
|
#include "Test.h"
|
|
|
|
/*
|
|
* Subclass of looper that just draws once, with an offset in X.
|
|
*/
|
|
class TestLooper : public SkDrawLooper {
|
|
public:
|
|
|
|
SkDrawLooper::Context* makeContext(SkCanvas*, SkArenaAlloc* alloc) const override {
|
|
return alloc->make<TestDrawLooperContext>();
|
|
}
|
|
|
|
sk_sp<SkDrawLooper> onMakeColorSpace(SkColorSpaceXformer*) const override {
|
|
return nullptr;
|
|
}
|
|
|
|
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(TestLooper)
|
|
|
|
private:
|
|
class TestDrawLooperContext : public SkDrawLooper::Context {
|
|
public:
|
|
TestDrawLooperContext() : fOnce(true) {}
|
|
~TestDrawLooperContext() override {}
|
|
|
|
bool next(SkCanvas* canvas, SkPaint*) override {
|
|
if (fOnce) {
|
|
fOnce = false;
|
|
canvas->translate(SkIntToScalar(10), 0);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private:
|
|
bool fOnce;
|
|
};
|
|
};
|
|
|
|
sk_sp<SkFlattenable> TestLooper::CreateProc(SkReadBuffer&) { return sk_make_sp<TestLooper>(); }
|
|
|
|
static void test_drawBitmap(skiatest::Reporter* reporter) {
|
|
SkBitmap src;
|
|
src.allocN32Pixels(10, 10);
|
|
src.eraseColor(SK_ColorWHITE);
|
|
|
|
SkBitmap dst;
|
|
dst.allocN32Pixels(10, 10);
|
|
dst.eraseColor(SK_ColorTRANSPARENT);
|
|
|
|
SkCanvas canvas(dst);
|
|
SkPaint paint;
|
|
|
|
// we are initially transparent
|
|
REPORTER_ASSERT(reporter, 0 == *dst.getAddr32(5, 5));
|
|
|
|
// we see the bitmap drawn
|
|
canvas.drawBitmap(src, 0, 0, &paint);
|
|
REPORTER_ASSERT(reporter, 0xFFFFFFFF == *dst.getAddr32(5, 5));
|
|
|
|
// reverify we are clear again
|
|
dst.eraseColor(SK_ColorTRANSPARENT);
|
|
REPORTER_ASSERT(reporter, 0 == *dst.getAddr32(5, 5));
|
|
|
|
// if the bitmap is clipped out, we don't draw it
|
|
canvas.drawBitmap(src, SkIntToScalar(-10), 0, &paint);
|
|
REPORTER_ASSERT(reporter, 0 == *dst.getAddr32(5, 5));
|
|
|
|
// now install our looper, which will draw, since it internally translates
|
|
// to the left. The test is to ensure that canvas' quickReject machinary
|
|
// allows us through, even though sans-looper we would look like we should
|
|
// be clipped out.
|
|
paint.setLooper(sk_make_sp<TestLooper>());
|
|
canvas.drawBitmap(src, SkIntToScalar(-10), 0, &paint);
|
|
REPORTER_ASSERT(reporter, 0xFFFFFFFF == *dst.getAddr32(5, 5));
|
|
}
|
|
|
|
static void test_layers(skiatest::Reporter* reporter) {
|
|
SkCanvas canvas(100, 100);
|
|
|
|
SkRect r = SkRect::MakeWH(10, 10);
|
|
REPORTER_ASSERT(reporter, false == canvas.quickReject(r));
|
|
|
|
r.offset(300, 300);
|
|
REPORTER_ASSERT(reporter, true == canvas.quickReject(r));
|
|
|
|
// Test that saveLayer updates quickReject
|
|
SkRect bounds = SkRect::MakeLTRB(50, 50, 70, 70);
|
|
canvas.saveLayer(&bounds, nullptr);
|
|
REPORTER_ASSERT(reporter, true == canvas.quickReject(SkRect::MakeWH(10, 10)));
|
|
REPORTER_ASSERT(reporter, false == canvas.quickReject(SkRect::MakeWH(60, 60)));
|
|
}
|
|
|
|
static void test_quick_reject(skiatest::Reporter* reporter) {
|
|
SkCanvas canvas(100, 100);
|
|
SkRect r0 = SkRect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
|
|
SkRect r1 = SkRect::MakeLTRB(-50.0f, 110.0f, 50.0f, 120.0f);
|
|
SkRect r2 = SkRect::MakeLTRB(110.0f, -50.0f, 120.0f, 50.0f);
|
|
SkRect r3 = SkRect::MakeLTRB(-120.0f, -50.0f, 120.0f, 50.0f);
|
|
SkRect r4 = SkRect::MakeLTRB(-50.0f, -120.0f, 50.0f, 120.0f);
|
|
SkRect r5 = SkRect::MakeLTRB(-120.0f, -120.0f, 120.0f, 120.0f);
|
|
SkRect r6 = SkRect::MakeLTRB(-120.0f, -120.0f, -110.0f, -110.0f);
|
|
SkRect r7 = SkRect::MakeLTRB(SK_ScalarNaN, -50.0f, 50.0f, 50.0f);
|
|
SkRect r8 = SkRect::MakeLTRB(-50.0f, SK_ScalarNaN, 50.0f, 50.0f);
|
|
SkRect r9 = SkRect::MakeLTRB(-50.0f, -50.0f, SK_ScalarNaN, 50.0f);
|
|
SkRect r10 = SkRect::MakeLTRB(-50.0f, -50.0f, 50.0f, SK_ScalarNaN);
|
|
REPORTER_ASSERT(reporter, false == canvas.quickReject(r0));
|
|
REPORTER_ASSERT(reporter, true == canvas.quickReject(r1));
|
|
REPORTER_ASSERT(reporter, true == canvas.quickReject(r2));
|
|
REPORTER_ASSERT(reporter, false == canvas.quickReject(r3));
|
|
REPORTER_ASSERT(reporter, false == canvas.quickReject(r4));
|
|
REPORTER_ASSERT(reporter, false == canvas.quickReject(r5));
|
|
REPORTER_ASSERT(reporter, true == canvas.quickReject(r6));
|
|
REPORTER_ASSERT(reporter, true == canvas.quickReject(r7));
|
|
REPORTER_ASSERT(reporter, true == canvas.quickReject(r8));
|
|
REPORTER_ASSERT(reporter, true == canvas.quickReject(r9));
|
|
REPORTER_ASSERT(reporter, true == canvas.quickReject(r10));
|
|
|
|
SkMatrix m = SkMatrix::MakeScale(2.0f);
|
|
m.setTranslateX(10.0f);
|
|
m.setTranslateY(10.0f);
|
|
canvas.setMatrix(m);
|
|
SkRect r11 = SkRect::MakeLTRB(5.0f, 5.0f, 100.0f, 100.0f);
|
|
SkRect r12 = SkRect::MakeLTRB(5.0f, 50.0f, 100.0f, 100.0f);
|
|
SkRect r13 = SkRect::MakeLTRB(50.0f, 5.0f, 100.0f, 100.0f);
|
|
REPORTER_ASSERT(reporter, false == canvas.quickReject(r11));
|
|
REPORTER_ASSERT(reporter, true == canvas.quickReject(r12));
|
|
REPORTER_ASSERT(reporter, true == canvas.quickReject(r13));
|
|
}
|
|
|
|
DEF_TEST(QuickReject, reporter) {
|
|
test_drawBitmap(reporter);
|
|
test_layers(reporter);
|
|
test_quick_reject(reporter);
|
|
}
|
|
|
|
// Regression test to make sure that we keep fIsScaleTranslate up to date on the canvas.
|
|
// It is possible to set a new matrix on the canvas without calling setMatrix(). This tests
|
|
// that code path.
|
|
DEF_TEST(QuickReject_MatrixState, reporter) {
|
|
SkCanvas canvas(100, 100);
|
|
|
|
SkMatrix matrix;
|
|
matrix.setRotate(45.0f);
|
|
canvas.setMatrix(matrix);
|
|
|
|
SkPaint paint;
|
|
sk_sp<SkImageFilter> filter = SkLightingImageFilter::MakeDistantLitDiffuse(
|
|
SkPoint3::Make(1.0f, 1.0f, 1.0f), 0xFF0000FF, 2.0f, 0.5f, nullptr);
|
|
REPORTER_ASSERT(reporter, filter);
|
|
paint.setImageFilter(filter);
|
|
SkCanvas::SaveLayerRec rec;
|
|
rec.fPaint = &paint;
|
|
canvas.saveLayer(rec);
|
|
|
|
// quickReject() will assert if the matrix is out of sync.
|
|
canvas.quickReject(SkRect::MakeWH(100.0f, 100.0f));
|
|
}
|
|
|
|
#include "SkLayerDrawLooper.h"
|
|
#include "SkSurface.h"
|
|
DEF_TEST(looper_nothingtodraw, reporter) {
|
|
auto surf = SkSurface::MakeRasterN32Premul(20, 20);
|
|
|
|
SkPaint paint;
|
|
paint.setColor(0);
|
|
REPORTER_ASSERT(reporter, paint.nothingToDraw());
|
|
|
|
SkLayerDrawLooper::Builder builder;
|
|
builder.addLayer();
|
|
paint.setDrawLooper(builder.detach());
|
|
// the presence of the looper fools this predicate, so we think it might draw
|
|
REPORTER_ASSERT(reporter, !paint.nothingToDraw());
|
|
|
|
// Before fixing, this would assert in ~AutoDrawLooper() in SkCanvas.cpp as it checked for
|
|
// a balance in the save/restore count after handling the looper. Before the fix, this
|
|
// code would call nothingToDraw() and since it now clears the looper, that predicate will
|
|
// return true, aborting the sequence prematurely, and not finishing the iterator on the looper
|
|
// which handles the final "restore". This was a bug -- we *must* call the looper's iterator
|
|
// until it returns done to keep the canvas balanced. The fix was to remove this early-exit
|
|
// in the autodrawlooper. Now this call won't assert.
|
|
// See https://skia-review.googlesource.com/c/skia/+/121220
|
|
surf->getCanvas()->drawRect({1, 1, 10, 10}, paint);
|
|
}
|