1 #include "Test.h" 2 #include "SkLazyPtr.h" 3 #include "SkRunnable.h" 4 #include "SkTaskGroup.h" 5 6 namespace { 7 8 struct CreateIntFromFloat { 9 CreateIntFromFloat(float val) : fVal(val) {} 10 int* operator()() const { return SkNEW_ARGS(int, ((int)fVal)); } 11 float fVal; 12 }; 13 14 // As a template argument this must have external linkage. 15 void custom_destroy(int* ptr) { *ptr = 99; } 16 17 } // namespace 18 19 DEF_TEST(LazyPtr, r) { 20 // Basic usage: calls SkNEW(int). 21 SkLazyPtr<int> lazy; 22 int* ptr = lazy.get(); 23 REPORTER_ASSERT(r, ptr); 24 REPORTER_ASSERT(r, lazy.get() == ptr); 25 26 // Advanced usage: calls a functor. 27 SkLazyPtr<int> lazyFunctor; 28 int* six = lazyFunctor.get(CreateIntFromFloat(6.4f)); 29 REPORTER_ASSERT(r, six); 30 REPORTER_ASSERT(r, 6 == *six); 31 32 // Just makes sure this is safe. 33 SkLazyPtr<double> neverRead; 34 35 // SkLazyPtr supports custom destroy methods. 36 { 37 SkLazyPtr<int, custom_destroy> customDestroy; 38 ptr = customDestroy.get(); 39 // custom_destroy called here. 40 } 41 REPORTER_ASSERT(r, ptr); 42 REPORTER_ASSERT(r, 99 == *ptr); 43 // Since custom_destroy didn't actually delete ptr, we do now. 44 SkDELETE(ptr); 45 } 46 47 namespace { 48 49 struct Racer : public SkRunnable { 50 Racer() : fLazy(NULL), fSeen(NULL) {} 51 52 void run() override { fSeen = fLazy->get(); } 53 54 SkLazyPtr<int>* fLazy; 55 int* fSeen; 56 }; 57 58 } // namespace 59 60 DEF_TEST(LazyPtr_Threaded, r) { 61 static const int kRacers = 321; 62 63 SkLazyPtr<int> lazy; 64 65 Racer racers[kRacers]; 66 for (int i = 0; i < kRacers; i++) { 67 racers[i].fLazy = &lazy; 68 } 69 70 SkTaskGroup tg; 71 for (int i = 0; i < kRacers; i++) { 72 tg.add(racers + i); 73 } 74 tg.wait(); 75 76 for (int i = 1; i < kRacers; i++) { 77 REPORTER_ASSERT(r, racers[i].fSeen); 78 REPORTER_ASSERT(r, racers[i].fSeen == racers[0].fSeen); 79 } 80 } 81