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