1c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org/* 2c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org * Copyright 2014 Google Inc. 3c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org * 4c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be 5c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org * found in the LICENSE file. 6c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org */ 7c4b21e6c03a6cdb03e116b9f510eb10cf8daedb1commit-bot@chromium.org 8d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "Test.h" 90a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org#include "RecordTestUtils.h" 10d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org 11d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkDebugCanvas.h" 12271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein#include "SkDropShadowImageFilter.h" 1365151754b9fdb6a968d7307764c20655d1b680a0piotaixr#include "SkImagePriv.h" 14d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecord.h" 15d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecordDraw.h" 16271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein#include "SkRecordOpts.h" 17d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecorder.h" 18d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecords.h" 1965151754b9fdb6a968d7307764c20655d1b680a0piotaixr#include "SkSurface.h" 20d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org 21d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.orgstatic const int W = 1920, H = 1080; 22d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org 23783fe16b8ed1cd1cff34eacc33296874a32f293brobertphillipsclass JustOneDraw : public SkPicture::AbortCallback { 24c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinpublic: 25c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein JustOneDraw() : fCalls(0) {} 26c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 2736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool abort() override { return fCalls++ > 0; } 28c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinprivate: 29c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein int fCalls; 30c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein}; 31c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 322ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedDEF_TEST(RecordDraw_LazySaves, r) { 332ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // Record two commands. 342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRecord record; 352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRecorder recorder(&record, W, H); 362ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 372ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 0 == record.count()); 382ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.save(); 392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 0 == record.count()); // the save was not recorded (yet) 402ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.drawColor(SK_ColorRED); 412ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 1 == record.count()); 422ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.scale(2, 2); 432ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 3 == record.count()); // now we see the save 442ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.restore(); 452ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 4 == record.count()); 462ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 472ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed assert_type<SkRecords::DrawPaint>(r, record, 0); 482ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed assert_type<SkRecords::Save> (r, record, 1); 49e9d2052e4931eeade49042a855b9c1f5ab7c84c5mtklein assert_type<SkRecords::Concat> (r, record, 2); 502ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed assert_type<SkRecords::Restore> (r, record, 3); 512ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 522ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.save(); 532ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.save(); 542ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.restore(); 552ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.restore(); 562ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 4 == record.count()); 572ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 582ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 59c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Abort, r) { 60c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein // Record two commands. 61c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecord record; 62c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecorder recorder(&record, W, H); 63c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein recorder.drawRect(SkRect::MakeWH(200, 300), SkPaint()); 64c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein recorder.clipRect(SkRect::MakeWH(100, 200)); 65c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 66c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecord rerecord; 67c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecorder canvas(&rerecord, W, H); 68c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 69c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein JustOneDraw callback; 7096fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkRecordDraw(record, &canvas, nullptr, nullptr, 0, nullptr/*bbh*/, &callback); 71c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 722ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 1 == count_instances_of_type<SkRecords::DrawRect>(rerecord)); 732ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 0 == count_instances_of_type<SkRecords::ClipRect>(rerecord)); 74c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein} 75c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 76c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Unbalanced, r) { 77c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecord record; 78c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecorder recorder(&record, W, H); 79c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein recorder.save(); // We won't balance this, but SkRecordDraw will for us. 802ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.scale(2, 2); 81c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 82c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecord rerecord; 83c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecorder canvas(&rerecord, W, H); 8496fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkRecordDraw(record, &canvas, nullptr, nullptr, 0, nullptr/*bbh*/, nullptr/*callback*/); 85c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 862ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int save_count = count_instances_of_type<SkRecords::Save>(rerecord); 872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int restore_count = count_instances_of_type<SkRecords::Save>(rerecord); 882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, save_count == restore_count); 89c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein} 90c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 910a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.orgDEF_TEST(RecordDraw_SetMatrixClobber, r) { 920a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org // Set up an SkRecord that just scales by 2x,3x. 930a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkRecord scaleRecord; 94a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org SkRecorder scaleCanvas(&scaleRecord, W, H); 950a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkMatrix scale; 960a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org scale.setScale(2, 3); 970a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org scaleCanvas.setMatrix(scale); 980a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org 990a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org // Set up an SkRecord with an initial +20, +20 translate. 1000a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkRecord translateRecord; 101a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org SkRecorder translateCanvas(&translateRecord, W, H); 1020a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkMatrix translate; 1030a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org translate.setTranslate(20, 20); 1040a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org translateCanvas.setMatrix(translate); 1050a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org 10696fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkRecordDraw(scaleRecord, &translateCanvas, nullptr, nullptr, 0, nullptr/*bbh*/, nullptr/*callback*/); 107c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein REPORTER_ASSERT(r, 4 == translateRecord.count()); 108c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::SetMatrix>(r, translateRecord, 0); 109c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::Save> (r, translateRecord, 1); 110c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::SetMatrix>(r, translateRecord, 2); 111c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::Restore> (r, translateRecord, 3); 1120a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org 1130a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org // When we look at translateRecord now, it should have its first +20,+20 translate, 1140a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org // then a 2x,3x scale that's been concatted with that +20,+20 translate. 1150a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org const SkRecords::SetMatrix* setMatrix; 1160a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 0); 1170a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org REPORTER_ASSERT(r, setMatrix->matrix == translate); 1180a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org 119c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 2); 1200a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkMatrix expected = scale; 1210a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org expected.postConcat(translate); 1220a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org REPORTER_ASSERT(r, setMatrix->matrix == expected); 1230a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org} 124a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 125937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein// Like a==b, with a little slop recognizing that float equality can be weird. 126937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtkleinstatic bool sloppy_rect_eq(SkRect a, SkRect b) { 127937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein SkRect inset(a), outset(a); 128937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein inset.inset(1, 1); 129937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein outset.outset(1, 1); 130937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein return outset.contains(b) && !inset.contains(b); 131937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein} 132937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 13340732b34a1bf94eb44ee4b2327eece8d97735f11mtkleinDEF_TEST(RecordDraw_BasicBounds, r) { 134a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein SkRecord record; 135a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein SkRecorder recorder(&record, W, H); 136a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.save(); 137a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.clipRect(SkRect::MakeWH(400, 500)); 138a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.scale(2, 2); 139a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.drawRect(SkRect::MakeWH(320, 240), SkPaint()); 140a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.restore(); 141a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 14240732b34a1bf94eb44ee4b2327eece8d97735f11mtklein SkAutoTMalloc<SkRect> bounds(record.count()); 14340732b34a1bf94eb44ee4b2327eece8d97735f11mtklein SkRecordFillBounds(SkRect::MakeWH(SkIntToScalar(W), SkIntToScalar(H)), record, bounds); 144a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 14540732b34a1bf94eb44ee4b2327eece8d97735f11mtklein for (int i = 0; i < record.count(); i++) { 14640732b34a1bf94eb44ee4b2327eece8d97735f11mtklein REPORTER_ASSERT(r, sloppy_rect_eq(SkRect::MakeWH(400, 480), bounds[i])); 147a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein } 148a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein} 14900f30bdc9e34b013da54b4406f36556c5be8d041mtklein 150937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein// A regression test for crbug.com/409110. 151937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtkleinDEF_TEST(RecordDraw_TextBounds, r) { 152937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein SkRecord record; 153937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein SkRecorder recorder(&record, W, H); 154937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 155937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein // Two Chinese characters in UTF-8. 156937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein const char text[] = { '\xe6', '\xbc', '\xa2', '\xe5', '\xad', '\x97' }; 157937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein const size_t bytes = SK_ARRAY_COUNT(text); 158937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 159937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein const SkScalar xpos[] = { 10, 20 }; 160937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein recorder.drawPosTextH(text, bytes, xpos, 30, SkPaint()); 161937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 162937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein const SkPoint pos[] = { {40, 50}, {60, 70} }; 163937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein recorder.drawPosText(text, bytes, pos, SkPaint()); 164937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 16540732b34a1bf94eb44ee4b2327eece8d97735f11mtklein SkAutoTMalloc<SkRect> bounds(record.count()); 16640732b34a1bf94eb44ee4b2327eece8d97735f11mtklein SkRecordFillBounds(SkRect::MakeWH(SkIntToScalar(W), SkIntToScalar(H)), record, bounds); 167937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 1689a5380dd358a9c559a41beef7cb368cd7f0ca51fmtklein // We can make these next assertions confidently because SkRecordFillBounds 1699a5380dd358a9c559a41beef7cb368cd7f0ca51fmtklein // builds its bounds by overestimating font metrics in a platform-independent way. 1709a5380dd358a9c559a41beef7cb368cd7f0ca51fmtklein // If that changes, these tests will need to be more flexible. 17140732b34a1bf94eb44ee4b2327eece8d97735f11mtklein REPORTER_ASSERT(r, sloppy_rect_eq(bounds[0], SkRect::MakeLTRB(0, 0, 140, 60))); 17240732b34a1bf94eb44ee4b2327eece8d97735f11mtklein REPORTER_ASSERT(r, sloppy_rect_eq(bounds[1], SkRect::MakeLTRB(0, 20, 180, 100))); 173937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein} 174937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 17500f30bdc9e34b013da54b4406f36556c5be8d041mtklein// Base test to ensure start/stop range is respected 17600f30bdc9e34b013da54b4406f36556c5be8d041mtkleinDEF_TEST(RecordDraw_PartialStartStop, r) { 17700f30bdc9e34b013da54b4406f36556c5be8d041mtklein static const int kWidth = 10, kHeight = 10; 17800f30bdc9e34b013da54b4406f36556c5be8d041mtklein 17900f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRect r1 = { 0, 0, kWidth, kHeight }; 18000f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRect r2 = { 0, 0, kWidth, kHeight/2 }; 18100f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRect r3 = { 0, 0, kWidth/2, kHeight }; 18200f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkPaint p; 18300f30bdc9e34b013da54b4406f36556c5be8d041mtklein 18400f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecord record; 18500f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecorder recorder(&record, kWidth, kHeight); 18600f30bdc9e34b013da54b4406f36556c5be8d041mtklein recorder.drawRect(r1, p); 18700f30bdc9e34b013da54b4406f36556c5be8d041mtklein recorder.drawRect(r2, p); 18800f30bdc9e34b013da54b4406f36556c5be8d041mtklein recorder.drawRect(r3, p); 18900f30bdc9e34b013da54b4406f36556c5be8d041mtklein 19000f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecord rerecord; 19100f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecorder canvas(&rerecord, kWidth, kHeight); 19296fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkRecordPartialDraw(record, &canvas, nullptr, 0, 1, 2, SkMatrix::I()); // replay just drawRect of r2 19300f30bdc9e34b013da54b4406f36556c5be8d041mtklein 1942ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 1 == count_instances_of_type<SkRecords::DrawRect>(rerecord)); 1952ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int index = find_first_instances_of_type<SkRecords::DrawRect>(rerecord); 1962ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, index); 19700f30bdc9e34b013da54b4406f36556c5be8d041mtklein REPORTER_ASSERT(r, drawRect->rect == r2); 19800f30bdc9e34b013da54b4406f36556c5be8d041mtklein} 19900f30bdc9e34b013da54b4406f36556c5be8d041mtklein 2006950de6c4166fabb35e6c756fc009e0cf1c47819halcanary// A regression test for crbug.com/415468 and https://bug.skia.org/2957 . 2018e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// 2028e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// This also now serves as a regression test for crbug.com/418417. We used to adjust the 2038e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// bounds for the saveLayer, clip, and restore to be greater than the bounds of the picture. 2048e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// (We were applying the saveLayer paint to the bounds after restore, which makes no sense.) 205271a030f5d0d3c59715fbeffb31c761279f3f8caMike KleinDEF_TEST(RecordDraw_SaveLayerAffectsClipBounds, r) { 206271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein SkRecord record; 207271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein SkRecorder recorder(&record, 50, 50); 208271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein 209271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein // We draw a rectangle with a long drop shadow. We used to not update the clip 210271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein // bounds based on SaveLayer paints, so the drop shadow could be cut off. 211271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein SkPaint paint; 212c416912da4840af0c49bd8cdcf00044ed39500f6robertphillips paint.setImageFilter(SkDropShadowImageFilter::Make( 213c416912da4840af0c49bd8cdcf00044ed39500f6robertphillips 20, 0, 0, 0, SK_ColorBLACK, 214c416912da4840af0c49bd8cdcf00044ed39500f6robertphillips SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, 215c416912da4840af0c49bd8cdcf00044ed39500f6robertphillips nullptr)); 216271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein 21796fcdcc219d2a0d3579719b84b28bede76efba64halcanary recorder.saveLayer(nullptr, &paint); 218271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein recorder.clipRect(SkRect::MakeWH(20, 40)); 219271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein recorder.drawRect(SkRect::MakeWH(20, 40), SkPaint()); 220271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein recorder.restore(); 221271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein 2228e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // Under the original bug, the right edge value of the drawRect would be 20 less than asserted 2238e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // here because we intersected it with a clip that had not been adjusted for the drop shadow. 2248e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // 2258e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // The second bug showed up as adjusting the picture bounds (0,0,50,50) by the drop shadow too. 2268e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // The saveLayer, clipRect, and restore bounds were incorrectly (0,0,70,50). 22740732b34a1bf94eb44ee4b2327eece8d97735f11mtklein SkAutoTMalloc<SkRect> bounds(record.count()); 22840732b34a1bf94eb44ee4b2327eece8d97735f11mtklein SkRecordFillBounds(SkRect::MakeWH(50, 50), record, bounds); 22940732b34a1bf94eb44ee4b2327eece8d97735f11mtklein REPORTER_ASSERT(r, sloppy_rect_eq(bounds[0], SkRect::MakeLTRB(0, 0, 50, 50))); 23040732b34a1bf94eb44ee4b2327eece8d97735f11mtklein REPORTER_ASSERT(r, sloppy_rect_eq(bounds[1], SkRect::MakeLTRB(0, 0, 50, 50))); 23140732b34a1bf94eb44ee4b2327eece8d97735f11mtklein REPORTER_ASSERT(r, sloppy_rect_eq(bounds[2], SkRect::MakeLTRB(0, 0, 40, 40))); 23240732b34a1bf94eb44ee4b2327eece8d97735f11mtklein REPORTER_ASSERT(r, sloppy_rect_eq(bounds[3], SkRect::MakeLTRB(0, 0, 50, 50))); 233271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein} 23465151754b9fdb6a968d7307764c20655d1b680a0piotaixr 2354d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips// When a saveLayer provides an explicit bound and has a complex paint (e.g., one that 2364d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips// affects transparent black), that bound should serve to shrink the area of the required 2374d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips// backing store. 2384d52afef5cf90a2fed3bb69db71675c6450ab397robertphillipsDEF_TEST(RecordDraw_SaveLayerBoundsAffectsClipBounds, r) { 2394d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecord record; 2404d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecorder recorder(&record, 50, 50); 2414d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips 2424d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkPaint p; 243374772bd61951f01bf84fe17bf53d8867681c9aereed p.setBlendMode(SkBlendMode::kSrc); 2444d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips 24540732b34a1bf94eb44ee4b2327eece8d97735f11mtklein SkRect layerBounds = SkRect::MakeLTRB(10, 10, 40, 40); 24640732b34a1bf94eb44ee4b2327eece8d97735f11mtklein recorder.saveLayer(&layerBounds, &p); 2474d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips recorder.drawRect(SkRect::MakeLTRB(20, 20, 30, 30), SkPaint()); 2484d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips recorder.restore(); 2494d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips 25040732b34a1bf94eb44ee4b2327eece8d97735f11mtklein SkAutoTMalloc<SkRect> bounds(record.count()); 25140732b34a1bf94eb44ee4b2327eece8d97735f11mtklein SkRecordFillBounds(SkRect::MakeWH(50, 50), record, bounds); 252d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed if (!SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds()) { 25340732b34a1bf94eb44ee4b2327eece8d97735f11mtklein REPORTER_ASSERT(r, sloppy_rect_eq(bounds[0], SkRect::MakeLTRB(10, 10, 40, 40))); 25440732b34a1bf94eb44ee4b2327eece8d97735f11mtklein REPORTER_ASSERT(r, sloppy_rect_eq(bounds[1], SkRect::MakeLTRB(20, 20, 30, 30))); 25540732b34a1bf94eb44ee4b2327eece8d97735f11mtklein REPORTER_ASSERT(r, sloppy_rect_eq(bounds[2], SkRect::MakeLTRB(10, 10, 40, 40))); 256d990e2f14f14c36c3d0beb303dd0953c7aa1fcfareed } 2574d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips} 2584d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips 25965151754b9fdb6a968d7307764c20655d1b680a0piotaixrDEF_TEST(RecordDraw_drawImage, r){ 26065151754b9fdb6a968d7307764c20655d1b680a0piotaixr class SkCanvasMock : public SkCanvas { 26165151754b9fdb6a968d7307764c20655d1b680a0piotaixr public: 262ad8aa1dcf36d64ddf849b914281713b901a01f49mtklein SkCanvasMock(int width, int height) : SkCanvas(width, height) { 26365151754b9fdb6a968d7307764c20655d1b680a0piotaixr this->resetTestValues(); 26465151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 26565151754b9fdb6a968d7307764c20655d1b680a0piotaixr 26641af966ab338e95eee81ab618ab28195075338f7reed void onDrawImage(const SkImage* image, SkScalar left, SkScalar top, 26736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const SkPaint* paint) override { 26865151754b9fdb6a968d7307764c20655d1b680a0piotaixr fDrawImageCalled = true; 26965151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 27065151754b9fdb6a968d7307764c20655d1b680a0piotaixr 27141af966ab338e95eee81ab618ab28195075338f7reed void onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, 272562fe4767cc73e08a4e039362bc0336aea66ecfbreed const SkPaint* paint, SrcRectConstraint) override { 27365151754b9fdb6a968d7307764c20655d1b680a0piotaixr fDrawImageRectCalled = true; 27465151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 27565151754b9fdb6a968d7307764c20655d1b680a0piotaixr 27665151754b9fdb6a968d7307764c20655d1b680a0piotaixr void resetTestValues() { 27765151754b9fdb6a968d7307764c20655d1b680a0piotaixr fDrawImageCalled = fDrawImageRectCalled = false; 27865151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 27965151754b9fdb6a968d7307764c20655d1b680a0piotaixr 28065151754b9fdb6a968d7307764c20655d1b680a0piotaixr bool fDrawImageCalled; 28165151754b9fdb6a968d7307764c20655d1b680a0piotaixr bool fDrawImageRectCalled; 28265151754b9fdb6a968d7307764c20655d1b680a0piotaixr }; 28365151754b9fdb6a968d7307764c20655d1b680a0piotaixr 284e8f3062a36d3682f4019309a32b5b84dc9eddf8creed auto surface(SkSurface::MakeRasterN32Premul(10, 10)); 28565151754b9fdb6a968d7307764c20655d1b680a0piotaixr surface->getCanvas()->clear(SK_ColorGREEN); 2869ce9d6772df650ceb0511f275e1a83dffa78ff72reed sk_sp<SkImage> image(surface->makeImageSnapshot()); 28765151754b9fdb6a968d7307764c20655d1b680a0piotaixr 28865151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkCanvasMock canvas(10, 10); 28965151754b9fdb6a968d7307764c20655d1b680a0piotaixr 29065151754b9fdb6a968d7307764c20655d1b680a0piotaixr { 29165151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecord record; 29265151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecorder recorder(&record, 10, 10); 29365151754b9fdb6a968d7307764c20655d1b680a0piotaixr recorder.drawImage(image, 0, 0); 29496fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkRecordDraw(record, &canvas, nullptr, nullptr, 0, nullptr, 0); 29565151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 29665151754b9fdb6a968d7307764c20655d1b680a0piotaixr REPORTER_ASSERT(r, canvas.fDrawImageCalled); 29765151754b9fdb6a968d7307764c20655d1b680a0piotaixr canvas.resetTestValues(); 29865151754b9fdb6a968d7307764c20655d1b680a0piotaixr 29965151754b9fdb6a968d7307764c20655d1b680a0piotaixr { 30065151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecord record; 30165151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecorder recorder(&record, 10, 10); 302e47829b6b1eeb6b0c97ccb3df3016d197046824creed recorder.drawImageRect(image, SkRect::MakeWH(10, 10), nullptr); 30396fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkRecordDraw(record, &canvas, nullptr, nullptr, 0, nullptr, 0); 30465151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 30565151754b9fdb6a968d7307764c20655d1b680a0piotaixr REPORTER_ASSERT(r, canvas.fDrawImageRectCalled); 30665151754b9fdb6a968d7307764c20655d1b680a0piotaixr 30765151754b9fdb6a968d7307764c20655d1b680a0piotaixr} 308