1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2014 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "tests/Test.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/core/SkPictureRecorder.h" 11cb93a386Sopenharmony_ci#include "include/core/SkShader.h" 12cb93a386Sopenharmony_ci#include "include/core/SkSurface.h" 13cb93a386Sopenharmony_ci#include "src/core/SkRecord.h" 14cb93a386Sopenharmony_ci#include "src/core/SkRecorder.h" 15cb93a386Sopenharmony_ci#include "src/core/SkRecords.h" 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ci#define COUNT(T) + 1 18cb93a386Sopenharmony_cistatic const int kRecordTypes = SK_RECORD_TYPES(COUNT); 19cb93a386Sopenharmony_ci#undef COUNT 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ci// Tallies the types of commands it sees into a histogram. 22cb93a386Sopenharmony_ciclass Tally { 23cb93a386Sopenharmony_cipublic: 24cb93a386Sopenharmony_ci Tally() { sk_bzero(&fHistogram, sizeof(fHistogram)); } 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci template <typename T> 27cb93a386Sopenharmony_ci void operator()(const T&) { ++fHistogram[T::kType]; } 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci template <typename T> 30cb93a386Sopenharmony_ci int count() const { return fHistogram[T::kType]; } 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci void apply(const SkRecord& record) { 33cb93a386Sopenharmony_ci for (int i = 0; i < record.count(); i++) { 34cb93a386Sopenharmony_ci record.visit(i, *this); 35cb93a386Sopenharmony_ci } 36cb93a386Sopenharmony_ci } 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ciprivate: 39cb93a386Sopenharmony_ci int fHistogram[kRecordTypes]; 40cb93a386Sopenharmony_ci}; 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ciDEF_TEST(Recorder, r) { 43cb93a386Sopenharmony_ci SkRecord record; 44cb93a386Sopenharmony_ci SkRecorder recorder(&record, 1920, 1080); 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ci recorder.drawRect(SkRect::MakeWH(10, 10), SkPaint()); 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ci Tally tally; 49cb93a386Sopenharmony_ci tally.apply(record); 50cb93a386Sopenharmony_ci REPORTER_ASSERT(r, 1 == tally.count<SkRecords::DrawRect>()); 51cb93a386Sopenharmony_ci} 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci// Regression test for leaking refs held by optional arguments. 54cb93a386Sopenharmony_ciDEF_TEST(Recorder_RefLeaking, r) { 55cb93a386Sopenharmony_ci // We use SaveLayer to test: 56cb93a386Sopenharmony_ci // - its SkRect argument is optional and SkRect is POD. Just testing that that works. 57cb93a386Sopenharmony_ci // - its SkPaint argument is optional and SkPaint is not POD. The bug was here. 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci SkRect bounds = SkRect::MakeWH(320, 240); 60cb93a386Sopenharmony_ci SkPaint paint; 61cb93a386Sopenharmony_ci paint.setShader(SkShaders::Empty()); 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci REPORTER_ASSERT(r, paint.getShader()->unique()); 64cb93a386Sopenharmony_ci { 65cb93a386Sopenharmony_ci SkRecord record; 66cb93a386Sopenharmony_ci SkRecorder recorder(&record, 1920, 1080); 67cb93a386Sopenharmony_ci recorder.saveLayer(&bounds, &paint); 68cb93a386Sopenharmony_ci REPORTER_ASSERT(r, !paint.getShader()->unique()); 69cb93a386Sopenharmony_ci } 70cb93a386Sopenharmony_ci REPORTER_ASSERT(r, paint.getShader()->unique()); 71cb93a386Sopenharmony_ci} 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ciDEF_TEST(Recorder_drawImage_takeReference, reporter) { 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci sk_sp<SkImage> image; 76cb93a386Sopenharmony_ci { 77cb93a386Sopenharmony_ci auto surface(SkSurface::MakeRasterN32Premul(100, 100)); 78cb93a386Sopenharmony_ci surface->getCanvas()->clear(SK_ColorGREEN); 79cb93a386Sopenharmony_ci image = surface->makeImageSnapshot(); 80cb93a386Sopenharmony_ci } 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci { 83cb93a386Sopenharmony_ci SkRecord record; 84cb93a386Sopenharmony_ci SkRecorder recorder(&record, 100, 100); 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci // DrawImage is supposed to take a reference 87cb93a386Sopenharmony_ci recorder.drawImage(image.get(), 0, 0, SkSamplingOptions()); 88cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !image->unique()); 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_ci Tally tally; 91cb93a386Sopenharmony_ci tally.apply(record); 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 1 == tally.count<SkRecords::DrawImage>()); 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, image->unique()); 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci { 98cb93a386Sopenharmony_ci SkRecord record; 99cb93a386Sopenharmony_ci SkRecorder recorder(&record, 100, 100); 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ci // DrawImageRect is supposed to take a reference 102cb93a386Sopenharmony_ci recorder.drawImageRect(image.get(), SkRect::MakeWH(100, 100), SkRect::MakeWH(100, 100), 103cb93a386Sopenharmony_ci SkSamplingOptions(), nullptr, SkCanvas::kFast_SrcRectConstraint); 104cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, !image->unique()); 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_ci Tally tally; 107cb93a386Sopenharmony_ci tally.apply(record); 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 1 == tally.count<SkRecords::DrawImageRect>()); 110cb93a386Sopenharmony_ci } 111cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, image->unique()); 112cb93a386Sopenharmony_ci} 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci// skbug.com/10997 115cb93a386Sopenharmony_ciDEF_TEST(Recorder_boundsOverflow, reporter) { 116cb93a386Sopenharmony_ci SkRect bigBounds = {SK_ScalarMin, SK_ScalarMin, SK_ScalarMax, SK_ScalarMax}; 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci SkRecord record; 119cb93a386Sopenharmony_ci SkRecorder recorder(&record, bigBounds); 120cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, recorder.imageInfo().width() > 0 && 121cb93a386Sopenharmony_ci recorder.imageInfo().height() > 0); 122cb93a386Sopenharmony_ci} 123