Make sure pictures draw Clears even when the clip is empty.
We fix this by rewriting empty queries to very tiny queries, which will certainly hit ops that span the entire picture (like Clear) and hopefully not much more. (This doesn't quite work in the full cull rect world if [0,0,ε,ε] doesn't overlap the picture. Let's cross that bridge when we get there.) BUG=432991 Review URL: https://codereview.chromium.org/732723004
This commit is contained in:
parent
9176e2c159
commit
7cc1a34fbf
@ -22,8 +22,12 @@ void SkRecordDraw(const SkRecord& record,
|
||||
// is not necessarily in that same space. getClipBounds() returns us
|
||||
// this canvas' clip bounds transformed back into identity space, which
|
||||
// lets us query the BBH.
|
||||
SkRect query = { 0, 0, 0, 0 };
|
||||
(void)canvas->getClipBounds(&query);
|
||||
SkRect query;
|
||||
if (!canvas->getClipBounds(&query)) {
|
||||
// We want to make sure our query rectangle is never totally empty.
|
||||
// Clear ignores the clip, so it must draw even if the clip is logically empty.
|
||||
query = SkRect::MakeWH(SK_ScalarNearlyZero, SK_ScalarNearlyZero);
|
||||
}
|
||||
|
||||
SkTDArray<unsigned> ops;
|
||||
bbh->search(query, &ops);
|
||||
|
@ -49,7 +49,9 @@ private:
|
||||
SkCanvas playbackCanvas(fResultBitmap);
|
||||
playbackCanvas.clear(SK_ColorGREEN);
|
||||
SkPictureRecorder recorder;
|
||||
SkCanvas* recordCanvas = recorder.beginRecording(SkIntToScalar(fPictureWidth), SkIntToScalar(fPictureHeight), factory);
|
||||
SkCanvas* recordCanvas = recorder.beginRecording(SkIntToScalar(fPictureWidth),
|
||||
SkIntToScalar(fPictureHeight),
|
||||
factory);
|
||||
this->doTest(playbackCanvas, *recordCanvas);
|
||||
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
|
||||
playbackCanvas.drawPicture(picture);
|
||||
@ -99,3 +101,34 @@ DEF_TEST(PictureBBH, reporter) {
|
||||
EmptyClipPictureBBHTest emptyClipPictureTest;
|
||||
emptyClipPictureTest.run(reporter);
|
||||
}
|
||||
|
||||
static void test_clear(skiatest::Reporter* r, SkBBHFactory* factory) {
|
||||
// SkPicture should always call clear()s on the target canvas, even if its clip is empty.
|
||||
SkPictureRecorder src, dst;
|
||||
|
||||
// A picture that's just clear().
|
||||
src.beginRecording(1,1, factory)
|
||||
->clear(SK_ColorGREEN);
|
||||
SkAutoTDelete<SkPicture> srcPic(src.endRecording());
|
||||
|
||||
// A target canvas with an empty clip.
|
||||
SkCanvas* c = dst.beginRecording(1,1, NULL);
|
||||
c->clipRect(SkRect::MakeEmpty());
|
||||
srcPic->playback(c);
|
||||
SkAutoTDelete<SkPicture> dstPic(dst.endRecording());
|
||||
|
||||
// Should be Clip - Save - Clear - Restore.
|
||||
// Buggy implementations might return 1 (just Clip) or 3 (Clip - Save - Restore).
|
||||
REPORTER_ASSERT(r, dstPic->approximateOpCount() == 4);
|
||||
}
|
||||
|
||||
DEF_TEST(PictureBBH_Clear, r) {
|
||||
test_clear(r, NULL);
|
||||
|
||||
SkTileGridFactory::TileGridInfo grid = { {1,1}, {0,0}, {0,0} };
|
||||
SkTileGridFactory tilegrid(grid);
|
||||
test_clear(r, &tilegrid);
|
||||
|
||||
SkRTreeFactory rtree;
|
||||
test_clear(r, &rtree);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user