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