Fix two SkRecord-backed layer hoisting bugs

The two bugs are/were:
The old loop to draw the hoisted layers included the saveLayer call which caused double application of the layer's paint (This is the +1 change).

The hoisted layer is intended to be drawn in device coordinates. The old code was drawing it in the coordinate space of the saveLayer thus it was misplaced (This is the setMatrix change).

Committed: https://skia.googlesource.com/skia/+/7c0cfd4ff8f6db50a8731c886db732b106268937

R=bsalomon@google.com

Author: robertphillips@google.com

Review URL: https://codereview.chromium.org/551843002
This commit is contained in:
robertphillips 2014-09-08 11:37:59 -07:00 committed by Commit bot
parent 858baf5b7d
commit 46625e06e2
3 changed files with 19 additions and 10 deletions

View File

@ -95,7 +95,7 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture,
atlasCanvas->concat(layer->ctm());
SkRecordPartialDraw(*picture->fRecord.get(), atlasCanvas, bound,
layer->start(), layer->stop());
layer->start()+1, layer->stop());
atlasCanvas->restore();
}
@ -129,7 +129,7 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture,
layerCanvas->concat(layer->ctm());
SkRecordPartialDraw(*picture->fRecord.get(), layerCanvas, bound,
layer->start(), layer->stop());
layer->start()+1, layer->stop());
layerCanvas->flush();
}

View File

@ -51,13 +51,18 @@ GrReplacements::lookupByStart(size_t start, int* searchStart) const {
}
static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo* ri,
SkCanvas* canvas) {
SkCanvas* canvas,
const SkMatrix& initialMatrix) {
SkRect src = SkRect::Make(ri->fSrcRect);
SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX),
SkIntToScalar(ri->fPos.fY),
SkIntToScalar(ri->fSrcRect.width()),
SkIntToScalar(ri->fSrcRect.height()));
canvas->save();
canvas->setMatrix(initialMatrix);
ri->fImage->draw(canvas, &src, dst, ri->fPaint);
canvas->restore();
}
void GrRecordReplaceDraw(const SkRecord& record,
@ -71,6 +76,8 @@ void GrRecordReplaceDraw(const SkRecord& record,
const GrReplacements::ReplacementInfo* ri = NULL;
int searchStart = 0;
const SkMatrix initialMatrix = canvas->getTotalMatrix();
if (bbh) {
// Draw only ops that affect pixels in the canvas's current clip.
// The SkRecord and BBH were recorded in identity space. This canvas
@ -89,7 +96,7 @@ void GrRecordReplaceDraw(const SkRecord& record,
}
ri = replacements->lookupByStart((uintptr_t)ops[i], &searchStart);
if (ri) {
draw_replacement_bitmap(ri, canvas);
draw_replacement_bitmap(ri, canvas, initialMatrix);
while ((uintptr_t)ops[i] < ri->fStop) {
++i;
@ -107,8 +114,7 @@ void GrRecordReplaceDraw(const SkRecord& record,
}
ri = replacements->lookupByStart(i, &searchStart);
if (ri) {
draw_replacement_bitmap(ri, canvas);
draw_replacement_bitmap(ri, canvas, initialMatrix);
i = ri->fStop;
continue;
}

View File

@ -112,11 +112,14 @@ void test_replacements(skiatest::Reporter* r, bool useBBH) {
SkRecorder canvas(&rerecord, kWidth, kHeight);
GrRecordReplaceDraw(record, &canvas, bbh, &replacements, NULL/*callback*/);
REPORTER_ASSERT(r, 4 == rerecord.count());
REPORTER_ASSERT(r, 7 == rerecord.count());
assert_type<SkRecords::Save>(r, rerecord, 0);
assert_type<SkRecords::DrawBitmapRectToRect>(r, rerecord, 1);
assert_type<SkRecords::DrawRect>(r, rerecord, 2);
assert_type<SkRecords::Restore>(r, rerecord, 3);
assert_type<SkRecords::Save>(r, rerecord, 1);
assert_type<SkRecords::SetMatrix>(r, rerecord, 2);
assert_type<SkRecords::DrawBitmapRectToRect>(r, rerecord, 3);
assert_type<SkRecords::Restore>(r, rerecord, 4);
assert_type<SkRecords::DrawRect>(r, rerecord, 5);
assert_type<SkRecords::Restore>(r, rerecord, 6);
}
DEF_TEST(RecordReplaceDraw_Replace, r) { test_replacements(r, false); }