RecordDrawTest.cpp revision 9a5380dd358a9c559a41beef7cb368cd7f0ca51f
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" 12c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein#include "SkDrawPictureCallback.h" 13271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein#include "SkDropShadowImageFilter.h" 1465151754b9fdb6a968d7307764c20655d1b680a0piotaixr#include "SkImagePriv.h" 15d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecord.h" 16d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecordDraw.h" 17271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein#include "SkRecordOpts.h" 18d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecorder.h" 19d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org#include "SkRecords.h" 2065151754b9fdb6a968d7307764c20655d1b680a0piotaixr#include "SkSurface.h" 21d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org 22d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.orgstatic const int W = 1920, H = 1080; 23d9ce2be6b24b1c89d13c2edb63c3462b0f5c6aa3commit-bot@chromium.org 24c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinclass JustOneDraw : public SkDrawPictureCallback { 25c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinpublic: 26c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein JustOneDraw() : fCalls(0) {} 27c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 28c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein virtual bool abortDrawing() SK_OVERRIDE { return fCalls++ > 0; } 29c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Kleinprivate: 30c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein int fCalls; 31c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein}; 32c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 332ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreedDEF_TEST(RecordDraw_LazySaves, r) { 342ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed // Record two commands. 352ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRecord record; 362ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed SkRecorder recorder(&record, W, H); 372ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 382ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 0 == record.count()); 392ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.save(); 402ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 0 == record.count()); // the save was not recorded (yet) 412ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.drawColor(SK_ColorRED); 422ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 1 == record.count()); 432ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.scale(2, 2); 442ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 3 == record.count()); // now we see the save 452ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.restore(); 462ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 4 == record.count()); 472ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 482ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed assert_type<SkRecords::DrawPaint>(r, record, 0); 492ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed assert_type<SkRecords::Save> (r, record, 1); 502ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed assert_type<SkRecords::SetMatrix>(r, record, 2); 512ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed assert_type<SkRecords::Restore> (r, record, 3); 522ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 532ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.save(); 542ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.save(); 552ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.restore(); 562ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.restore(); 572ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 4 == record.count()); 582ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed} 592ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed 60c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Abort, r) { 61c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein // Record two commands. 62c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecord record; 63c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecorder recorder(&record, W, H); 64c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein recorder.drawRect(SkRect::MakeWH(200, 300), SkPaint()); 65c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein recorder.clipRect(SkRect::MakeWH(100, 200)); 66c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 67c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecord rerecord; 68c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecorder canvas(&rerecord, W, H); 69c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 70c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein JustOneDraw callback; 711bdfd3f4f09e47364f76d3f08177b1ce844ac786reed SkRecordDraw(record, &canvas, NULL, NULL, 0, NULL/*bbh*/, &callback); 72c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 732ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 1 == count_instances_of_type<SkRecords::DrawRect>(rerecord)); 742ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 0 == count_instances_of_type<SkRecords::ClipRect>(rerecord)); 75c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein} 76c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 77c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Unbalanced, r) { 78c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecord record; 79c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecorder recorder(&record, W, H); 80c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein recorder.save(); // We won't balance this, but SkRecordDraw will for us. 812ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed recorder.scale(2, 2); 82c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 83c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecord rerecord; 84c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecorder canvas(&rerecord, W, H); 851bdfd3f4f09e47364f76d3f08177b1ce844ac786reed SkRecordDraw(record, &canvas, NULL, NULL, 0, NULL/*bbh*/, NULL/*callback*/); 86c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 872ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int save_count = count_instances_of_type<SkRecords::Save>(rerecord); 882ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int restore_count = count_instances_of_type<SkRecords::Save>(rerecord); 892ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, save_count == restore_count); 90c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein} 91c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 920a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.orgDEF_TEST(RecordDraw_SetMatrixClobber, r) { 930a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org // Set up an SkRecord that just scales by 2x,3x. 940a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkRecord scaleRecord; 95a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org SkRecorder scaleCanvas(&scaleRecord, W, H); 960a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkMatrix scale; 970a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org scale.setScale(2, 3); 980a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org scaleCanvas.setMatrix(scale); 990a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org 1000a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org // Set up an SkRecord with an initial +20, +20 translate. 1010a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkRecord translateRecord; 102a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org SkRecorder translateCanvas(&translateRecord, W, H); 1030a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkMatrix translate; 1040a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org translate.setTranslate(20, 20); 1050a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org translateCanvas.setMatrix(translate); 1060a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org 1071bdfd3f4f09e47364f76d3f08177b1ce844ac786reed SkRecordDraw(scaleRecord, &translateCanvas, NULL, NULL, 0, NULL/*bbh*/, NULL/*callback*/); 108c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein REPORTER_ASSERT(r, 4 == translateRecord.count()); 109c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::SetMatrix>(r, translateRecord, 0); 110c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::Save> (r, translateRecord, 1); 111c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::SetMatrix>(r, translateRecord, 2); 112c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::Restore> (r, translateRecord, 3); 1130a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org 1140a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org // When we look at translateRecord now, it should have its first +20,+20 translate, 1150a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org // then a 2x,3x scale that's been concatted with that +20,+20 translate. 1160a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org const SkRecords::SetMatrix* setMatrix; 1170a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 0); 1180a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org REPORTER_ASSERT(r, setMatrix->matrix == translate); 1190a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org 120c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 2); 1210a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkMatrix expected = scale; 1220a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org expected.postConcat(translate); 1230a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org REPORTER_ASSERT(r, setMatrix->matrix == expected); 1240a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org} 125a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 126a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtkleinstruct TestBBH : public SkBBoxHierarchy { 1274477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein virtual void insert(SkAutoTMalloc<SkRect>* boundsArray, int N) SK_OVERRIDE { 1284477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein fEntries.setCount(N); 1294477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein for (int i = 0; i < N; i++) { 1304477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein Entry e = { (unsigned)i, (*boundsArray)[i] }; 1314477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein fEntries[i] = e; 1324477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein } 133a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein } 134a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 1356bd41969a0f2283a7a7320bb0025551353c241ecmtklein virtual void search(const SkRect& query, SkTDArray<unsigned>* results) const SK_OVERRIDE {} 136158fcaa031d105dc999d9813fee8927db56a871ctomhudson virtual size_t bytesUsed() const SK_OVERRIDE { return 0; } 137a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 138a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein struct Entry { 1396bd41969a0f2283a7a7320bb0025551353c241ecmtklein unsigned opIndex; 140533eb782edaa0b6fece6166d3001edf72ec39f11mtklein SkRect bounds; 141a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein }; 1426bd41969a0f2283a7a7320bb0025551353c241ecmtklein SkTDArray<Entry> fEntries; 143a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein}; 144a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 145937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein// Like a==b, with a little slop recognizing that float equality can be weird. 146937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtkleinstatic bool sloppy_rect_eq(SkRect a, SkRect b) { 147937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein SkRect inset(a), outset(a); 148937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein inset.inset(1, 1); 149937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein outset.outset(1, 1); 150937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein return outset.contains(b) && !inset.contains(b); 151937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein} 152937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 153a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein// This test is not meant to make total sense yet. It's testing the status quo 154a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein// of SkRecordFillBounds(), which itself doesn't make total sense yet. 155a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtkleinDEF_TEST(RecordDraw_BBH, r) { 156a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein SkRecord record; 157a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein SkRecorder recorder(&record, W, H); 158a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.save(); 159a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.clipRect(SkRect::MakeWH(400, 500)); 160a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.scale(2, 2); 161a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.drawRect(SkRect::MakeWH(320, 240), SkPaint()); 162a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.restore(); 163a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 164937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein TestBBH bbh; 1654d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecordFillBounds(SkRect::MakeWH(SkIntToScalar(W), SkIntToScalar(H)), record, &bbh); 166a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 1676bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, bbh.fEntries.count() == 5); 1686bd41969a0f2283a7a7320bb0025551353c241ecmtklein for (int i = 0; i < bbh.fEntries.count(); i++) { 1696bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, bbh.fEntries[i].opIndex == (unsigned)i); 170a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 1716bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, sloppy_rect_eq(SkRect::MakeWH(400, 480), bbh.fEntries[i].bounds)); 172a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein } 173a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein} 17400f30bdc9e34b013da54b4406f36556c5be8d041mtklein 175937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein// A regression test for crbug.com/409110. 176937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtkleinDEF_TEST(RecordDraw_TextBounds, r) { 177937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein SkRecord record; 178937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein SkRecorder recorder(&record, W, H); 179937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 180937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein // Two Chinese characters in UTF-8. 181937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein const char text[] = { '\xe6', '\xbc', '\xa2', '\xe5', '\xad', '\x97' }; 182937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein const size_t bytes = SK_ARRAY_COUNT(text); 183937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 184937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein const SkScalar xpos[] = { 10, 20 }; 185937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein recorder.drawPosTextH(text, bytes, xpos, 30, SkPaint()); 186937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 187937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein const SkPoint pos[] = { {40, 50}, {60, 70} }; 188937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein recorder.drawPosText(text, bytes, pos, SkPaint()); 189937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 190937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein TestBBH bbh; 1914d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecordFillBounds(SkRect::MakeWH(SkIntToScalar(W), SkIntToScalar(H)), record, &bbh); 1926bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, bbh.fEntries.count() == 2); 193937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 1949a5380dd358a9c559a41beef7cb368cd7f0ca51fmtklein // We can make these next assertions confidently because SkRecordFillBounds 1959a5380dd358a9c559a41beef7cb368cd7f0ca51fmtklein // builds its bounds by overestimating font metrics in a platform-independent way. 1969a5380dd358a9c559a41beef7cb368cd7f0ca51fmtklein // If that changes, these tests will need to be more flexible. 1979a5380dd358a9c559a41beef7cb368cd7f0ca51fmtklein REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[0].bounds, SkRect::MakeLTRB(0, 0, 140, 60))); 1989a5380dd358a9c559a41beef7cb368cd7f0ca51fmtklein REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[1].bounds, SkRect::MakeLTRB(0, 20, 180, 100))); 199937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein} 200937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 20100f30bdc9e34b013da54b4406f36556c5be8d041mtklein// Base test to ensure start/stop range is respected 20200f30bdc9e34b013da54b4406f36556c5be8d041mtkleinDEF_TEST(RecordDraw_PartialStartStop, r) { 20300f30bdc9e34b013da54b4406f36556c5be8d041mtklein static const int kWidth = 10, kHeight = 10; 20400f30bdc9e34b013da54b4406f36556c5be8d041mtklein 20500f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRect r1 = { 0, 0, kWidth, kHeight }; 20600f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRect r2 = { 0, 0, kWidth, kHeight/2 }; 20700f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRect r3 = { 0, 0, kWidth/2, kHeight }; 20800f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkPaint p; 20900f30bdc9e34b013da54b4406f36556c5be8d041mtklein 21000f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecord record; 21100f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecorder recorder(&record, kWidth, kHeight); 21200f30bdc9e34b013da54b4406f36556c5be8d041mtklein recorder.drawRect(r1, p); 21300f30bdc9e34b013da54b4406f36556c5be8d041mtklein recorder.drawRect(r2, p); 21400f30bdc9e34b013da54b4406f36556c5be8d041mtklein recorder.drawRect(r3, p); 21500f30bdc9e34b013da54b4406f36556c5be8d041mtklein 21600f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecord rerecord; 21700f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecorder canvas(&rerecord, kWidth, kHeight); 2188eddfb50c0c9e4bcba6384a2ce39852b5fb5becbreed SkRecordPartialDraw(record, &canvas, NULL, 0, 1, 2, SkMatrix::I()); // replay just drawRect of r2 21900f30bdc9e34b013da54b4406f36556c5be8d041mtklein 2202ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed REPORTER_ASSERT(r, 1 == count_instances_of_type<SkRecords::DrawRect>(rerecord)); 2212ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed int index = find_first_instances_of_type<SkRecords::DrawRect>(rerecord); 2222ff1fcede1e9525285c5de1f35fb2dcb0fab32bdreed const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, index); 22300f30bdc9e34b013da54b4406f36556c5be8d041mtklein REPORTER_ASSERT(r, drawRect->rect == r2); 22400f30bdc9e34b013da54b4406f36556c5be8d041mtklein} 22500f30bdc9e34b013da54b4406f36556c5be8d041mtklein 226271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein// A regression test for crbug.com/415468 and skbug.com/2957. 2278e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// 2288e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// This also now serves as a regression test for crbug.com/418417. We used to adjust the 2298e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// bounds for the saveLayer, clip, and restore to be greater than the bounds of the picture. 2308e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// (We were applying the saveLayer paint to the bounds after restore, which makes no sense.) 231271a030f5d0d3c59715fbeffb31c761279f3f8caMike KleinDEF_TEST(RecordDraw_SaveLayerAffectsClipBounds, r) { 232271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein SkRecord record; 233271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein SkRecorder recorder(&record, 50, 50); 234271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein 235271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein // We draw a rectangle with a long drop shadow. We used to not update the clip 236271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein // bounds based on SaveLayer paints, so the drop shadow could be cut off. 237271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein SkPaint paint; 238234f036b3e731e06e616c5291157d3bb4fbfdee2sugoi paint.setImageFilter(SkDropShadowImageFilter::Create(20, 0, 0, 0, SK_ColorBLACK, 239234f036b3e731e06e616c5291157d3bb4fbfdee2sugoi SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode))->unref(); 240271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein 241271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein recorder.saveLayer(NULL, &paint); 242271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein recorder.clipRect(SkRect::MakeWH(20, 40)); 243271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein recorder.drawRect(SkRect::MakeWH(20, 40), SkPaint()); 244271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein recorder.restore(); 245271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein 2468e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // Under the original bug, the right edge value of the drawRect would be 20 less than asserted 2478e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // here because we intersected it with a clip that had not been adjusted for the drop shadow. 2488e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // 2498e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // The second bug showed up as adjusting the picture bounds (0,0,50,50) by the drop shadow too. 2508e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // The saveLayer, clipRect, and restore bounds were incorrectly (0,0,70,50). 251271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein TestBBH bbh; 2524d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecordFillBounds(SkRect::MakeWH(50, 50), record, &bbh); 2536bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, bbh.fEntries.count() == 4); 2546bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[0].bounds, SkRect::MakeLTRB(0, 0, 50, 50))); 2556bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[1].bounds, SkRect::MakeLTRB(0, 0, 50, 50))); 2566bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[2].bounds, SkRect::MakeLTRB(0, 0, 40, 40))); 2576bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[3].bounds, SkRect::MakeLTRB(0, 0, 50, 50))); 258271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein} 25965151754b9fdb6a968d7307764c20655d1b680a0piotaixr 2604d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips// When a saveLayer provides an explicit bound and has a complex paint (e.g., one that 2614d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips// affects transparent black), that bound should serve to shrink the area of the required 2624d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips// backing store. 2634d52afef5cf90a2fed3bb69db71675c6450ab397robertphillipsDEF_TEST(RecordDraw_SaveLayerBoundsAffectsClipBounds, r) { 2644d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecord record; 2654d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecorder recorder(&record, 50, 50); 2664d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips 2674d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkPaint p; 2684d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips p.setXfermodeMode(SkXfermode::kSrc_Mode); 2694d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips 2704d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRect bounds = SkRect::MakeLTRB(10, 10, 40, 40); 2714d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips recorder.saveLayer(&bounds, &p); 2724d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips recorder.drawRect(SkRect::MakeLTRB(20, 20, 30, 30), SkPaint()); 2734d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips recorder.restore(); 2744d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips 2754d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips TestBBH bbh; 2764d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecordFillBounds(SkRect::MakeWH(50, 50), record, &bbh); 2774d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips REPORTER_ASSERT(r, bbh.fEntries.count() == 3); 2784d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[0].bounds, SkRect::MakeLTRB(10, 10, 40, 40))); 2794d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[1].bounds, SkRect::MakeLTRB(20, 20, 30, 30))); 2804d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[2].bounds, SkRect::MakeLTRB(10, 10, 40, 40))); 2814d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips} 2824d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips 28365151754b9fdb6a968d7307764c20655d1b680a0piotaixrDEF_TEST(RecordDraw_drawImage, r){ 28465151754b9fdb6a968d7307764c20655d1b680a0piotaixr class SkCanvasMock : public SkCanvas { 28565151754b9fdb6a968d7307764c20655d1b680a0piotaixr public: 286ad8aa1dcf36d64ddf849b914281713b901a01f49mtklein SkCanvasMock(int width, int height) : SkCanvas(width, height) { 28765151754b9fdb6a968d7307764c20655d1b680a0piotaixr this->resetTestValues(); 28865151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 28965151754b9fdb6a968d7307764c20655d1b680a0piotaixr virtual ~SkCanvasMock() {} 29065151754b9fdb6a968d7307764c20655d1b680a0piotaixr virtual void drawImage(const SkImage* image, SkScalar left, SkScalar top, 29165151754b9fdb6a968d7307764c20655d1b680a0piotaixr const SkPaint* paint = NULL) SK_OVERRIDE { 29265151754b9fdb6a968d7307764c20655d1b680a0piotaixr 29365151754b9fdb6a968d7307764c20655d1b680a0piotaixr fDrawImageCalled = true; 29465151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 29565151754b9fdb6a968d7307764c20655d1b680a0piotaixr 29665151754b9fdb6a968d7307764c20655d1b680a0piotaixr virtual void drawImageRect(const SkImage* image, const SkRect* src, 29765151754b9fdb6a968d7307764c20655d1b680a0piotaixr const SkRect& dst, 29865151754b9fdb6a968d7307764c20655d1b680a0piotaixr const SkPaint* paint = NULL) SK_OVERRIDE { 29965151754b9fdb6a968d7307764c20655d1b680a0piotaixr fDrawImageRectCalled = true; 30065151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 30165151754b9fdb6a968d7307764c20655d1b680a0piotaixr 30265151754b9fdb6a968d7307764c20655d1b680a0piotaixr void resetTestValues() { 30365151754b9fdb6a968d7307764c20655d1b680a0piotaixr fDrawImageCalled = fDrawImageRectCalled = false; 30465151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 30565151754b9fdb6a968d7307764c20655d1b680a0piotaixr 30665151754b9fdb6a968d7307764c20655d1b680a0piotaixr bool fDrawImageCalled; 30765151754b9fdb6a968d7307764c20655d1b680a0piotaixr bool fDrawImageRectCalled; 30865151754b9fdb6a968d7307764c20655d1b680a0piotaixr }; 30965151754b9fdb6a968d7307764c20655d1b680a0piotaixr 3103054be16dfdb0d06233770cbfc338958edef44eareed SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(10, 10)); 31165151754b9fdb6a968d7307764c20655d1b680a0piotaixr surface->getCanvas()->clear(SK_ColorGREEN); 31265151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); 31365151754b9fdb6a968d7307764c20655d1b680a0piotaixr 31465151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkCanvasMock canvas(10, 10); 31565151754b9fdb6a968d7307764c20655d1b680a0piotaixr 31665151754b9fdb6a968d7307764c20655d1b680a0piotaixr { 31765151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecord record; 31865151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecorder recorder(&record, 10, 10); 31965151754b9fdb6a968d7307764c20655d1b680a0piotaixr recorder.drawImage(image, 0, 0); 3201bdfd3f4f09e47364f76d3f08177b1ce844ac786reed SkRecordDraw(record, &canvas, NULL, NULL, 0, NULL, 0); 32165151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 32265151754b9fdb6a968d7307764c20655d1b680a0piotaixr REPORTER_ASSERT(r, canvas.fDrawImageCalled); 32365151754b9fdb6a968d7307764c20655d1b680a0piotaixr canvas.resetTestValues(); 32465151754b9fdb6a968d7307764c20655d1b680a0piotaixr 32565151754b9fdb6a968d7307764c20655d1b680a0piotaixr { 32665151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecord record; 32765151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecorder recorder(&record, 10, 10); 32865151754b9fdb6a968d7307764c20655d1b680a0piotaixr recorder.drawImageRect(image, 0, SkRect::MakeWH(10, 10)); 3291bdfd3f4f09e47364f76d3f08177b1ce844ac786reed SkRecordDraw(record, &canvas, NULL, NULL, 0, NULL, 0); 33065151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 33165151754b9fdb6a968d7307764c20655d1b680a0piotaixr REPORTER_ASSERT(r, canvas.fDrawImageRectCalled); 33265151754b9fdb6a968d7307764c20655d1b680a0piotaixr 33365151754b9fdb6a968d7307764c20655d1b680a0piotaixr} 334