RecordDrawTest.cpp revision ad8aa1dcf36d64ddf849b914281713b901a01f49
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 33c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Abort, r) { 34c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein // Record two commands. 35c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecord record; 36c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecorder recorder(&record, W, H); 37c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein recorder.drawRect(SkRect::MakeWH(200, 300), SkPaint()); 38c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein recorder.clipRect(SkRect::MakeWH(100, 200)); 39c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 40c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecord rerecord; 41c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecorder canvas(&rerecord, W, H); 42c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 43c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein JustOneDraw callback; 445ad6ee1b2ce54f8e59b9f5a337c688a98a4b0f2amtklein SkRecordDraw(record, &canvas, NULL/*bbh*/, &callback); 45c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 46c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein REPORTER_ASSERT(r, 3 == rerecord.count()); 47c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::Save> (r, rerecord, 0); 48c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::DrawRect>(r, rerecord, 1); 49c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::Restore> (r, rerecord, 2); 50c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein} 51c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 52c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike KleinDEF_TEST(RecordDraw_Unbalanced, r) { 53c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecord record; 54c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecorder recorder(&record, W, H); 55c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein recorder.save(); // We won't balance this, but SkRecordDraw will for us. 56c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 57c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecord rerecord; 58c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein SkRecorder canvas(&rerecord, W, H); 595ad6ee1b2ce54f8e59b9f5a337c688a98a4b0f2amtklein SkRecordDraw(record, &canvas, NULL/*bbh*/, NULL/*callback*/); 60c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 61c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein REPORTER_ASSERT(r, 4 == rerecord.count()); 62c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::Save> (r, rerecord, 0); 63c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::Save> (r, rerecord, 1); 64c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::Restore> (r, rerecord, 2); 65c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::Restore> (r, rerecord, 3); 66c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein} 67c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein 680a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.orgDEF_TEST(RecordDraw_SetMatrixClobber, r) { 690a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org // Set up an SkRecord that just scales by 2x,3x. 700a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkRecord scaleRecord; 71a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org SkRecorder scaleCanvas(&scaleRecord, W, H); 720a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkMatrix scale; 730a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org scale.setScale(2, 3); 740a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org scaleCanvas.setMatrix(scale); 750a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org 760a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org // Set up an SkRecord with an initial +20, +20 translate. 770a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkRecord translateRecord; 78a095041f5148dd1e71f38d0546335ed94199104bcommit-bot@chromium.org SkRecorder translateCanvas(&translateRecord, W, H); 790a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkMatrix translate; 800a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org translate.setTranslate(20, 20); 810a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org translateCanvas.setMatrix(translate); 820a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org 835ad6ee1b2ce54f8e59b9f5a337c688a98a4b0f2amtklein SkRecordDraw(scaleRecord, &translateCanvas, NULL/*bbh*/, NULL/*callback*/); 84c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein REPORTER_ASSERT(r, 4 == translateRecord.count()); 85c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::SetMatrix>(r, translateRecord, 0); 86c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::Save> (r, translateRecord, 1); 87c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::SetMatrix>(r, translateRecord, 2); 88c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein assert_type<SkRecords::Restore> (r, translateRecord, 3); 890a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org 900a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org // When we look at translateRecord now, it should have its first +20,+20 translate, 910a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org // then a 2x,3x scale that's been concatted with that +20,+20 translate. 920a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org const SkRecords::SetMatrix* setMatrix; 930a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 0); 940a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org REPORTER_ASSERT(r, setMatrix->matrix == translate); 950a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org 96c11530ea73b2a2fcb431df0f5c1887d08ac9113cMike Klein setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 2); 970a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org SkMatrix expected = scale; 980a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org expected.postConcat(translate); 990a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org REPORTER_ASSERT(r, setMatrix->matrix == expected); 1000a98d870448f66ea0df7c37a47b38cf2d3b734e5commit-bot@chromium.org} 101a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 102a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtkleinstruct TestBBH : public SkBBoxHierarchy { 1034477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein virtual void insert(SkAutoTMalloc<SkRect>* boundsArray, int N) SK_OVERRIDE { 1044477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein fEntries.setCount(N); 1054477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein for (int i = 0; i < N; i++) { 1064477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein Entry e = { (unsigned)i, (*boundsArray)[i] }; 1074477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein fEntries[i] = e; 1084477c3c0e6eb064772aefe8737425cd1c2ce557fmtklein } 109a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein } 110a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 1116bd41969a0f2283a7a7320bb0025551353c241ecmtklein virtual void search(const SkRect& query, SkTDArray<unsigned>* results) const SK_OVERRIDE {} 112a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 113a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein struct Entry { 1146bd41969a0f2283a7a7320bb0025551353c241ecmtklein unsigned opIndex; 115533eb782edaa0b6fece6166d3001edf72ec39f11mtklein SkRect bounds; 116a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein }; 1176bd41969a0f2283a7a7320bb0025551353c241ecmtklein SkTDArray<Entry> fEntries; 118a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein}; 119a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 120937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein// Like a==b, with a little slop recognizing that float equality can be weird. 121937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtkleinstatic bool sloppy_rect_eq(SkRect a, SkRect b) { 122937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein SkRect inset(a), outset(a); 123937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein inset.inset(1, 1); 124937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein outset.outset(1, 1); 125937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein return outset.contains(b) && !inset.contains(b); 126937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein} 127937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 128a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein// This test is not meant to make total sense yet. It's testing the status quo 129a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein// of SkRecordFillBounds(), which itself doesn't make total sense yet. 130a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtkleinDEF_TEST(RecordDraw_BBH, r) { 131a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein SkRecord record; 132a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein SkRecorder recorder(&record, W, H); 133a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.save(); 134a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.clipRect(SkRect::MakeWH(400, 500)); 135a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.scale(2, 2); 136a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.drawRect(SkRect::MakeWH(320, 240), SkPaint()); 137a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein recorder.restore(); 138a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 139937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein TestBBH bbh; 1404d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecordFillBounds(SkRect::MakeWH(SkIntToScalar(W), SkIntToScalar(H)), record, &bbh); 141a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 1426bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, bbh.fEntries.count() == 5); 1436bd41969a0f2283a7a7320bb0025551353c241ecmtklein for (int i = 0; i < bbh.fEntries.count(); i++) { 1446bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, bbh.fEntries[i].opIndex == (unsigned)i); 145a723b576aed31a6eb2bdda6388e6bd779d04c6b0mtklein 1466bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, sloppy_rect_eq(SkRect::MakeWH(400, 480), bbh.fEntries[i].bounds)); 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 165937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein TestBBH bbh; 1664d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecordFillBounds(SkRect::MakeWH(SkIntToScalar(W), SkIntToScalar(H)), record, &bbh); 1676bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, bbh.fEntries.count() == 2); 168937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 169ed167acb7b494bf0aece05ac8a68b560782b027cmtklein // We can make these next assertions confidently because SkRecordFillBounds 170ed167acb7b494bf0aece05ac8a68b560782b027cmtklein // builds its bounds by overestimating font metrics in a platform-independent way. 171ed167acb7b494bf0aece05ac8a68b560782b027cmtklein // If that changes, these tests will need to be more flexible. 1724d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[0].bounds, SkRect::MakeLTRB(0, 0, 140, 60))); 1734d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[1].bounds, SkRect::MakeLTRB(0, 20, 180, 100))); 174937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein} 175937c9c7eb4e06d4d3bc495e129c7b8103a5d6c0fmtklein 17600f30bdc9e34b013da54b4406f36556c5be8d041mtklein// Base test to ensure start/stop range is respected 17700f30bdc9e34b013da54b4406f36556c5be8d041mtkleinDEF_TEST(RecordDraw_PartialStartStop, r) { 17800f30bdc9e34b013da54b4406f36556c5be8d041mtklein static const int kWidth = 10, kHeight = 10; 17900f30bdc9e34b013da54b4406f36556c5be8d041mtklein 18000f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRect r1 = { 0, 0, kWidth, kHeight }; 18100f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRect r2 = { 0, 0, kWidth, kHeight/2 }; 18200f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRect r3 = { 0, 0, kWidth/2, kHeight }; 18300f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkPaint p; 18400f30bdc9e34b013da54b4406f36556c5be8d041mtklein 18500f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecord record; 18600f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecorder recorder(&record, kWidth, kHeight); 18700f30bdc9e34b013da54b4406f36556c5be8d041mtklein recorder.drawRect(r1, p); 18800f30bdc9e34b013da54b4406f36556c5be8d041mtklein recorder.drawRect(r2, p); 18900f30bdc9e34b013da54b4406f36556c5be8d041mtklein recorder.drawRect(r3, p); 19000f30bdc9e34b013da54b4406f36556c5be8d041mtklein 19100f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecord rerecord; 19200f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecorder canvas(&rerecord, kWidth, kHeight); 1934815fe5a0a497b676677fb4e4a0f05c511855490robertphillips SkRecordPartialDraw(record, &canvas, r1, 1, 2, SkMatrix::I()); // replay just drawRect of r2 19400f30bdc9e34b013da54b4406f36556c5be8d041mtklein 19500f30bdc9e34b013da54b4406f36556c5be8d041mtklein REPORTER_ASSERT(r, 3 == rerecord.count()); 19600f30bdc9e34b013da54b4406f36556c5be8d041mtklein assert_type<SkRecords::Save> (r, rerecord, 0); 19700f30bdc9e34b013da54b4406f36556c5be8d041mtklein assert_type<SkRecords::DrawRect> (r, rerecord, 1); 19800f30bdc9e34b013da54b4406f36556c5be8d041mtklein assert_type<SkRecords::Restore> (r, rerecord, 2); 19900f30bdc9e34b013da54b4406f36556c5be8d041mtklein 20000f30bdc9e34b013da54b4406f36556c5be8d041mtklein const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, 1); 20100f30bdc9e34b013da54b4406f36556c5be8d041mtklein REPORTER_ASSERT(r, drawRect->rect == r2); 20200f30bdc9e34b013da54b4406f36556c5be8d041mtklein} 20300f30bdc9e34b013da54b4406f36556c5be8d041mtklein 20400f30bdc9e34b013da54b4406f36556c5be8d041mtklein// Check that clears are converted to drawRects 20500f30bdc9e34b013da54b4406f36556c5be8d041mtkleinDEF_TEST(RecordDraw_PartialClear, r) { 20600f30bdc9e34b013da54b4406f36556c5be8d041mtklein static const int kWidth = 10, kHeight = 10; 20700f30bdc9e34b013da54b4406f36556c5be8d041mtklein 20800f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRect rect = { 0, 0, kWidth, kHeight }; 20900f30bdc9e34b013da54b4406f36556c5be8d041mtklein 21000f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecord record; 21100f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecorder recorder(&record, kWidth, kHeight); 21200f30bdc9e34b013da54b4406f36556c5be8d041mtklein recorder.clear(SK_ColorRED); 21300f30bdc9e34b013da54b4406f36556c5be8d041mtklein 21400f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecord rerecord; 21500f30bdc9e34b013da54b4406f36556c5be8d041mtklein SkRecorder canvas(&rerecord, kWidth, kHeight); 2164815fe5a0a497b676677fb4e4a0f05c511855490robertphillips SkRecordPartialDraw(record, &canvas, rect, 0, 1, SkMatrix::I()); // replay just the clear 21700f30bdc9e34b013da54b4406f36556c5be8d041mtklein 21800f30bdc9e34b013da54b4406f36556c5be8d041mtklein REPORTER_ASSERT(r, 3 == rerecord.count()); 21900f30bdc9e34b013da54b4406f36556c5be8d041mtklein assert_type<SkRecords::Save> (r, rerecord, 0); 22000f30bdc9e34b013da54b4406f36556c5be8d041mtklein assert_type<SkRecords::DrawRect>(r, rerecord, 1); 22100f30bdc9e34b013da54b4406f36556c5be8d041mtklein assert_type<SkRecords::Restore> (r, rerecord, 2); 22200f30bdc9e34b013da54b4406f36556c5be8d041mtklein 22300f30bdc9e34b013da54b4406f36556c5be8d041mtklein const SkRecords::DrawRect* drawRect = assert_type<SkRecords::DrawRect>(r, rerecord, 1); 22400f30bdc9e34b013da54b4406f36556c5be8d041mtklein REPORTER_ASSERT(r, drawRect->rect == rect); 22500f30bdc9e34b013da54b4406f36556c5be8d041mtklein REPORTER_ASSERT(r, drawRect->paint.getColor() == SK_ColorRED); 22600f30bdc9e34b013da54b4406f36556c5be8d041mtklein} 227271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein 228271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein// A regression test for crbug.com/415468 and skbug.com/2957. 2298e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// 2308e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// This also now serves as a regression test for crbug.com/418417. We used to adjust the 2318e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// bounds for the saveLayer, clip, and restore to be greater than the bounds of the picture. 2328e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein// (We were applying the saveLayer paint to the bounds after restore, which makes no sense.) 233271a030f5d0d3c59715fbeffb31c761279f3f8caMike KleinDEF_TEST(RecordDraw_SaveLayerAffectsClipBounds, r) { 234271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein SkRecord record; 235271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein SkRecorder recorder(&record, 50, 50); 236271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein 237271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein // We draw a rectangle with a long drop shadow. We used to not update the clip 238271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein // bounds based on SaveLayer paints, so the drop shadow could be cut off. 239271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein SkPaint paint; 240234f036b3e731e06e616c5291157d3bb4fbfdee2sugoi paint.setImageFilter(SkDropShadowImageFilter::Create(20, 0, 0, 0, SK_ColorBLACK, 241234f036b3e731e06e616c5291157d3bb4fbfdee2sugoi SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode))->unref(); 242271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein 243271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein recorder.saveLayer(NULL, &paint); 244271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein recorder.clipRect(SkRect::MakeWH(20, 40)); 245271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein recorder.drawRect(SkRect::MakeWH(20, 40), SkPaint()); 246271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein recorder.restore(); 247271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein 2488e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // Under the original bug, the right edge value of the drawRect would be 20 less than asserted 2498e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // here because we intersected it with a clip that had not been adjusted for the drop shadow. 2508e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // 2518e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // The second bug showed up as adjusting the picture bounds (0,0,50,50) by the drop shadow too. 2528e393bf70ea2aab9ca31f52c15b518436c7b6055mtklein // The saveLayer, clipRect, and restore bounds were incorrectly (0,0,70,50). 253271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein TestBBH bbh; 2544d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecordFillBounds(SkRect::MakeWH(50, 50), record, &bbh); 2556bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, bbh.fEntries.count() == 4); 2566bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[0].bounds, SkRect::MakeLTRB(0, 0, 50, 50))); 2576bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[1].bounds, SkRect::MakeLTRB(0, 0, 50, 50))); 2586bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[2].bounds, SkRect::MakeLTRB(0, 0, 40, 40))); 2596bd41969a0f2283a7a7320bb0025551353c241ecmtklein REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[3].bounds, SkRect::MakeLTRB(0, 0, 50, 50))); 260271a030f5d0d3c59715fbeffb31c761279f3f8caMike Klein} 26165151754b9fdb6a968d7307764c20655d1b680a0piotaixr 2624d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips// When a saveLayer provides an explicit bound and has a complex paint (e.g., one that 2634d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips// affects transparent black), that bound should serve to shrink the area of the required 2644d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips// backing store. 2654d52afef5cf90a2fed3bb69db71675c6450ab397robertphillipsDEF_TEST(RecordDraw_SaveLayerBoundsAffectsClipBounds, r) { 2664d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecord record; 2674d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecorder recorder(&record, 50, 50); 2684d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips 2694d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkPaint p; 2704d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips p.setXfermodeMode(SkXfermode::kSrc_Mode); 2714d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips 2724d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRect bounds = SkRect::MakeLTRB(10, 10, 40, 40); 2734d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips recorder.saveLayer(&bounds, &p); 2744d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips recorder.drawRect(SkRect::MakeLTRB(20, 20, 30, 30), SkPaint()); 2754d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips recorder.restore(); 2764d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips 2774d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips TestBBH bbh; 2784d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips SkRecordFillBounds(SkRect::MakeWH(50, 50), record, &bbh); 2794d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips REPORTER_ASSERT(r, bbh.fEntries.count() == 3); 2804d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[0].bounds, SkRect::MakeLTRB(10, 10, 40, 40))); 2814d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[1].bounds, SkRect::MakeLTRB(20, 20, 30, 30))); 2824d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips REPORTER_ASSERT(r, sloppy_rect_eq(bbh.fEntries[2].bounds, SkRect::MakeLTRB(10, 10, 40, 40))); 2834d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips} 2844d52afef5cf90a2fed3bb69db71675c6450ab397robertphillips 28565151754b9fdb6a968d7307764c20655d1b680a0piotaixrDEF_TEST(RecordDraw_drawImage, r){ 28665151754b9fdb6a968d7307764c20655d1b680a0piotaixr class SkCanvasMock : public SkCanvas { 28765151754b9fdb6a968d7307764c20655d1b680a0piotaixr public: 288ad8aa1dcf36d64ddf849b914281713b901a01f49mtklein SkCanvasMock(int width, int height) : SkCanvas(width, height) { 28965151754b9fdb6a968d7307764c20655d1b680a0piotaixr this->resetTestValues(); 29065151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 29165151754b9fdb6a968d7307764c20655d1b680a0piotaixr virtual ~SkCanvasMock() {} 29265151754b9fdb6a968d7307764c20655d1b680a0piotaixr virtual void drawImage(const SkImage* image, SkScalar left, SkScalar top, 29365151754b9fdb6a968d7307764c20655d1b680a0piotaixr const SkPaint* paint = NULL) SK_OVERRIDE { 29465151754b9fdb6a968d7307764c20655d1b680a0piotaixr 29565151754b9fdb6a968d7307764c20655d1b680a0piotaixr fDrawImageCalled = true; 29665151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 29765151754b9fdb6a968d7307764c20655d1b680a0piotaixr 29865151754b9fdb6a968d7307764c20655d1b680a0piotaixr virtual void drawImageRect(const SkImage* image, const SkRect* src, 29965151754b9fdb6a968d7307764c20655d1b680a0piotaixr const SkRect& dst, 30065151754b9fdb6a968d7307764c20655d1b680a0piotaixr const SkPaint* paint = NULL) SK_OVERRIDE { 30165151754b9fdb6a968d7307764c20655d1b680a0piotaixr fDrawImageRectCalled = true; 30265151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 30365151754b9fdb6a968d7307764c20655d1b680a0piotaixr 30465151754b9fdb6a968d7307764c20655d1b680a0piotaixr void resetTestValues() { 30565151754b9fdb6a968d7307764c20655d1b680a0piotaixr fDrawImageCalled = fDrawImageRectCalled = false; 30665151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 30765151754b9fdb6a968d7307764c20655d1b680a0piotaixr 30865151754b9fdb6a968d7307764c20655d1b680a0piotaixr bool fDrawImageCalled; 30965151754b9fdb6a968d7307764c20655d1b680a0piotaixr bool fDrawImageRectCalled; 31065151754b9fdb6a968d7307764c20655d1b680a0piotaixr }; 31165151754b9fdb6a968d7307764c20655d1b680a0piotaixr 31265151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(10, 10)); 31365151754b9fdb6a968d7307764c20655d1b680a0piotaixr surface->getCanvas()->clear(SK_ColorGREEN); 31465151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); 31565151754b9fdb6a968d7307764c20655d1b680a0piotaixr 31665151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkCanvasMock canvas(10, 10); 31765151754b9fdb6a968d7307764c20655d1b680a0piotaixr 31865151754b9fdb6a968d7307764c20655d1b680a0piotaixr { 31965151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecord record; 32065151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecorder recorder(&record, 10, 10); 32165151754b9fdb6a968d7307764c20655d1b680a0piotaixr recorder.drawImage(image, 0, 0); 32265151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecordDraw(record, &canvas, 0, 0); 32365151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 32465151754b9fdb6a968d7307764c20655d1b680a0piotaixr REPORTER_ASSERT(r, canvas.fDrawImageCalled); 32565151754b9fdb6a968d7307764c20655d1b680a0piotaixr canvas.resetTestValues(); 32665151754b9fdb6a968d7307764c20655d1b680a0piotaixr 32765151754b9fdb6a968d7307764c20655d1b680a0piotaixr { 32865151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecord record; 32965151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecorder recorder(&record, 10, 10); 33065151754b9fdb6a968d7307764c20655d1b680a0piotaixr recorder.drawImageRect(image, 0, SkRect::MakeWH(10, 10)); 33165151754b9fdb6a968d7307764c20655d1b680a0piotaixr SkRecordDraw(record, &canvas, 0, 0); 33265151754b9fdb6a968d7307764c20655d1b680a0piotaixr } 33365151754b9fdb6a968d7307764c20655d1b680a0piotaixr REPORTER_ASSERT(r, canvas.fDrawImageRectCalled); 33465151754b9fdb6a968d7307764c20655d1b680a0piotaixr 33565151754b9fdb6a968d7307764c20655d1b680a0piotaixr} 336