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 "SkDeque.h"
9 #include "SkLayerRasterizer.h"
10 #include "SkPaint.h"
11 #include "SkRasterizer.h"
12 #include "Test.h"
13 
14 class SkReadBuffer;
15 
16 // Dummy class to place on a paint just to ensure the paint's destructor
17 // is called.
18 // ONLY to be used by LayerRasterizer_destructor, since other tests may
19 // be run in a separate thread, and this class is not threadsafe.
20 class DummyRasterizer : public SkRasterizer {
21 public:
DummyRasterizer()22     DummyRasterizer()
23         : INHERITED()
24     {
25         // Not threadsafe. Only used in one thread.
26         gCount++;
27     }
28 
~DummyRasterizer()29     ~DummyRasterizer() {
30         // Not threadsafe. Only used in one thread.
31         gCount--;
32     }
33 
GetCount()34     static int GetCount() { return gCount; }
35 
36     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(DummyRasterizer);
37 
38 private:
39     static int gCount;
40 
41     typedef SkRasterizer INHERITED;
42 };
43 
44 int DummyRasterizer::gCount;
45 
CreateProc(SkReadBuffer &)46 SkFlattenable* DummyRasterizer::CreateProc(SkReadBuffer&) { return new DummyRasterizer; }
47 
48 // Check to make sure that the SkPaint in the layer has its destructor called.
DEF_TEST(LayerRasterizer_destructor,reporter)49 DEF_TEST(LayerRasterizer_destructor, reporter) {
50     {
51         SkPaint paint;
52         paint.setRasterizer(new DummyRasterizer)->unref();
53         REPORTER_ASSERT(reporter, DummyRasterizer::GetCount() == 1);
54 
55         SkLayerRasterizer::Builder builder;
56         builder.addLayer(paint);
57     }
58     REPORTER_ASSERT(reporter, DummyRasterizer::GetCount() == 0);
59 }
60 
61 class LayerRasterizerTester {
62 public:
CountLayers(const SkLayerRasterizer & layerRasterizer)63     static int CountLayers(const SkLayerRasterizer& layerRasterizer) {
64         return layerRasterizer.fLayers->count();
65     }
66 
GetLayers(const SkLayerRasterizer & layerRasterizer)67     static const SkDeque& GetLayers(const SkLayerRasterizer& layerRasterizer) {
68         return *layerRasterizer.fLayers;
69     }
70 };
71 
72 // MUST stay in sync with definition of SkLayerRasterizer_Rec in SkLayerRasterizer.cpp.
73 struct SkLayerRasterizer_Rec {
74     SkPaint     fPaint;
75     SkVector    fOffset;
76 };
77 
equals(const SkLayerRasterizer_Rec & rec1,const SkLayerRasterizer_Rec & rec2)78 static bool equals(const SkLayerRasterizer_Rec& rec1, const SkLayerRasterizer_Rec& rec2) {
79     return rec1.fPaint == rec2.fPaint && rec1.fOffset == rec2.fOffset;
80 }
81 
DEF_TEST(LayerRasterizer_copy,reporter)82 DEF_TEST(LayerRasterizer_copy, reporter) {
83     SkLayerRasterizer::Builder builder;
84     REPORTER_ASSERT(reporter, nullptr == builder.snapshotRasterizer());
85     SkPaint paint;
86     // Create a bunch of paints with different flags.
87     for (uint32_t flags = 0x01; flags < SkPaint::kAllFlags; flags <<= 1) {
88         paint.setFlags(flags);
89         builder.addLayer(paint, static_cast<SkScalar>(flags), static_cast<SkScalar>(flags));
90     }
91 
92     // Create a layer rasterizer with all the existing layers.
93     SkAutoTUnref<SkLayerRasterizer> firstCopy(builder.snapshotRasterizer());
94 
95     // Add one more layer.
96     paint.setFlags(SkPaint::kAllFlags);
97     builder.addLayer(paint);
98 
99     SkAutoTUnref<SkLayerRasterizer> oneLarger(builder.snapshotRasterizer());
100     SkAutoTUnref<SkLayerRasterizer> detached(builder.detachRasterizer());
101 
102     // Check the counts for consistency.
103     const int largerCount = LayerRasterizerTester::CountLayers(*oneLarger.get());
104     const int smallerCount = LayerRasterizerTester::CountLayers(*firstCopy.get());
105     REPORTER_ASSERT(reporter, largerCount == LayerRasterizerTester::CountLayers(*detached.get()));
106     REPORTER_ASSERT(reporter, smallerCount == largerCount - 1);
107 
108     const SkLayerRasterizer_Rec* recFirstCopy = nullptr;
109     const SkLayerRasterizer_Rec* recOneLarger = nullptr;
110     const SkLayerRasterizer_Rec* recDetached = nullptr;
111 
112     const SkDeque& layersFirstCopy = LayerRasterizerTester::GetLayers(*firstCopy.get());
113     const SkDeque& layersOneLarger = LayerRasterizerTester::GetLayers(*oneLarger.get());
114     const SkDeque& layersDetached = LayerRasterizerTester::GetLayers(*detached.get());
115 
116     // Ensure that our version of SkLayerRasterizer_Rec is the same as the one in
117     // SkLayerRasterizer.cpp - or at least the same size. If the order were switched, we
118     // would fail the test elsewhere.
119     REPORTER_ASSERT(reporter, layersFirstCopy.elemSize() == sizeof(SkLayerRasterizer_Rec));
120     REPORTER_ASSERT(reporter, layersOneLarger.elemSize() == sizeof(SkLayerRasterizer_Rec));
121     REPORTER_ASSERT(reporter, layersDetached.elemSize() == sizeof(SkLayerRasterizer_Rec));
122 
123     SkDeque::F2BIter iterFirstCopy(layersFirstCopy);
124     SkDeque::F2BIter iterOneLarger(layersOneLarger);
125     SkDeque::F2BIter iterDetached(layersDetached);
126 
127     for (int i = 0; i < largerCount; ++i) {
128         recFirstCopy = static_cast<const SkLayerRasterizer_Rec*>(iterFirstCopy.next());
129         recOneLarger = static_cast<const SkLayerRasterizer_Rec*>(iterOneLarger.next());
130         recDetached  = static_cast<const SkLayerRasterizer_Rec*>(iterDetached.next());
131 
132         REPORTER_ASSERT(reporter, equals(*recOneLarger, *recDetached));
133         if (smallerCount == i) {
134             REPORTER_ASSERT(reporter, recFirstCopy == nullptr);
135         } else {
136             REPORTER_ASSERT(reporter, equals(*recFirstCopy, *recOneLarger));
137         }
138     }
139 }
140 
DEF_TEST(LayerRasterizer_detachEmpty,reporter)141 DEF_TEST(LayerRasterizer_detachEmpty, reporter) {
142     SkLayerRasterizer::Builder builder;
143     REPORTER_ASSERT(reporter, nullptr == builder.detachRasterizer());
144 }
145