FlattenDrawableTest.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. * Copyright 2016 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. #include "include/core/SkCanvas.h"
  8. #include "include/core/SkDrawable.h"
  9. #include "include/core/SkFont.h"
  10. #include "include/core/SkPictureRecorder.h"
  11. #include "include/core/SkRect.h"
  12. #include "include/core/SkStream.h"
  13. #include "src/core/SkReadBuffer.h"
  14. #include "src/core/SkWriteBuffer.h"
  15. #include "tests/Test.h"
  16. class IntDrawable : public SkDrawable {
  17. public:
  18. IntDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
  19. : fA(a)
  20. , fB(b)
  21. , fC(c)
  22. , fD(d)
  23. {}
  24. void flatten(SkWriteBuffer& buffer) const override {
  25. buffer.writeUInt(fA);
  26. buffer.writeUInt(fB);
  27. buffer.writeUInt(fC);
  28. buffer.writeUInt(fD);
  29. }
  30. static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
  31. uint32_t a = buffer.readUInt();
  32. uint32_t b = buffer.readUInt();
  33. uint32_t c = buffer.readUInt();
  34. uint32_t d = buffer.readUInt();
  35. return sk_sp<IntDrawable>(new IntDrawable(a, b, c, d));
  36. }
  37. Factory getFactory() const override { return CreateProc; }
  38. uint32_t a() const { return fA; }
  39. uint32_t b() const { return fB; }
  40. uint32_t c() const { return fC; }
  41. uint32_t d() const { return fD; }
  42. const char* getTypeName() const override { return "IntDrawable"; }
  43. protected:
  44. SkRect onGetBounds() override { return SkRect::MakeEmpty(); }
  45. void onDraw(SkCanvas*) override {}
  46. private:
  47. uint32_t fA;
  48. uint32_t fB;
  49. uint32_t fC;
  50. uint32_t fD;
  51. };
  52. class PaintDrawable : public SkDrawable {
  53. public:
  54. PaintDrawable(const SkPaint& paint)
  55. : fPaint(paint)
  56. {}
  57. void flatten(SkWriteBuffer& buffer) const override {
  58. buffer.writePaint(fPaint);
  59. }
  60. static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
  61. SkPaint paint;
  62. buffer.readPaint(&paint, nullptr);
  63. return sk_sp<PaintDrawable>(new PaintDrawable(paint));
  64. }
  65. Factory getFactory() const override { return CreateProc; }
  66. const SkPaint& paint() const { return fPaint; }
  67. const char* getTypeName() const override { return "PaintDrawable"; }
  68. protected:
  69. SkRect onGetBounds() override { return SkRect::MakeEmpty(); }
  70. void onDraw(SkCanvas*) override {}
  71. private:
  72. SkPaint fPaint;
  73. };
  74. class CompoundDrawable : public SkDrawable {
  75. public:
  76. CompoundDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPaint& paint)
  77. : fIntDrawable(new IntDrawable(a, b, c, d))
  78. , fPaintDrawable(new PaintDrawable(paint))
  79. {}
  80. CompoundDrawable(IntDrawable* intDrawable, PaintDrawable* paintDrawable)
  81. : fIntDrawable(SkRef(intDrawable))
  82. , fPaintDrawable(SkRef(paintDrawable))
  83. {}
  84. void flatten(SkWriteBuffer& buffer) const override {
  85. buffer.writeFlattenable(fIntDrawable.get());
  86. buffer.writeFlattenable(fPaintDrawable.get());
  87. }
  88. static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
  89. sk_sp<SkFlattenable> intDrawable(
  90. buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
  91. SkASSERT(intDrawable);
  92. SkASSERT(!strcmp("IntDrawable", intDrawable->getTypeName()));
  93. sk_sp<SkFlattenable> paintDrawable(
  94. buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
  95. SkASSERT(paintDrawable);
  96. SkASSERT(!strcmp("PaintDrawable", paintDrawable->getTypeName()));
  97. return sk_sp<CompoundDrawable>(new CompoundDrawable((IntDrawable*) intDrawable.get(),
  98. (PaintDrawable*) paintDrawable.get()));
  99. }
  100. Factory getFactory() const override { return CreateProc; }
  101. IntDrawable* intDrawable() const { return fIntDrawable.get(); }
  102. PaintDrawable* paintDrawable() const { return fPaintDrawable.get(); }
  103. const char* getTypeName() const override { return "CompoundDrawable"; }
  104. protected:
  105. SkRect onGetBounds() override { return SkRect::MakeEmpty(); }
  106. void onDraw(SkCanvas*) override {}
  107. private:
  108. sk_sp<IntDrawable> fIntDrawable;
  109. sk_sp<PaintDrawable> fPaintDrawable;
  110. };
  111. class RootDrawable : public SkDrawable {
  112. public:
  113. RootDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPaint& paint,
  114. uint32_t e, uint32_t f, uint32_t g, uint32_t h, SkDrawable* drawable)
  115. : fCompoundDrawable(new CompoundDrawable(a, b, c, d, paint))
  116. , fIntDrawable(new IntDrawable(e, f, g, h))
  117. , fDrawable(SkRef(drawable))
  118. {}
  119. RootDrawable(CompoundDrawable* compoundDrawable, IntDrawable* intDrawable,
  120. SkDrawable* drawable)
  121. : fCompoundDrawable(SkRef(compoundDrawable))
  122. , fIntDrawable(SkRef(intDrawable))
  123. , fDrawable(SkRef(drawable))
  124. {}
  125. void flatten(SkWriteBuffer& buffer) const override {
  126. buffer.writeFlattenable(fCompoundDrawable.get());
  127. buffer.writeFlattenable(fIntDrawable.get());
  128. buffer.writeFlattenable(fDrawable.get());
  129. }
  130. static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
  131. sk_sp<SkFlattenable> compoundDrawable(
  132. buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
  133. SkASSERT(compoundDrawable);
  134. SkASSERT(!strcmp("CompoundDrawable", compoundDrawable->getTypeName()));
  135. sk_sp<SkFlattenable> intDrawable(
  136. buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
  137. SkASSERT(intDrawable);
  138. SkASSERT(!strcmp("IntDrawable", intDrawable->getTypeName()));
  139. sk_sp<SkFlattenable> drawable(
  140. buffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
  141. SkASSERT(drawable);
  142. return sk_sp<RootDrawable>(new RootDrawable((CompoundDrawable*) compoundDrawable.get(),
  143. (IntDrawable*) intDrawable.get(),
  144. (SkDrawable*) drawable.get()));
  145. }
  146. Factory getFactory() const override { return CreateProc; }
  147. CompoundDrawable* compoundDrawable() const { return fCompoundDrawable.get(); }
  148. IntDrawable* intDrawable() const { return fIntDrawable.get(); }
  149. SkDrawable* drawable() const { return fDrawable.get(); }
  150. const char* getTypeName() const override { return "RootDrawable"; }
  151. protected:
  152. SkRect onGetBounds() override { return SkRect::MakeEmpty(); }
  153. void onDraw(SkCanvas*) override {}
  154. private:
  155. sk_sp<CompoundDrawable> fCompoundDrawable;
  156. sk_sp<IntDrawable> fIntDrawable;
  157. sk_sp<SkDrawable> fDrawable;
  158. };
  159. // Register these drawables for deserialization some time before main().
  160. static struct Initializer {
  161. Initializer() {
  162. SK_REGISTER_FLATTENABLE(IntDrawable);
  163. SK_REGISTER_FLATTENABLE(PaintDrawable);
  164. SK_REGISTER_FLATTENABLE(CompoundDrawable);
  165. SK_REGISTER_FLATTENABLE(RootDrawable);
  166. }
  167. } initializer;
  168. DEF_TEST(FlattenDrawable, r) {
  169. // Create and serialize the test drawable
  170. sk_sp<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4));
  171. SkPaint paint;
  172. paint.setColor(SK_ColorBLUE);
  173. sk_sp<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 11, 12, drawable.get()));
  174. SkBinaryWriteBuffer writeBuffer;
  175. writeBuffer.writeFlattenable(root.get());
  176. // Copy the contents of the write buffer into a read buffer
  177. sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten());
  178. writeBuffer.writeToMemory(data->writable_data());
  179. SkReadBuffer readBuffer(data->data(), data->size());
  180. // Deserialize and verify the drawable
  181. sk_sp<SkDrawable> out((SkDrawable*)readBuffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
  182. REPORTER_ASSERT(r, out);
  183. REPORTER_ASSERT(r, !strcmp("RootDrawable", out->getTypeName()));
  184. RootDrawable* rootOut = (RootDrawable*) out.get();
  185. REPORTER_ASSERT(r, 5 == rootOut->compoundDrawable()->intDrawable()->a());
  186. REPORTER_ASSERT(r, 6 == rootOut->compoundDrawable()->intDrawable()->b());
  187. REPORTER_ASSERT(r, 7 == rootOut->compoundDrawable()->intDrawable()->c());
  188. REPORTER_ASSERT(r, 8 == rootOut->compoundDrawable()->intDrawable()->d());
  189. REPORTER_ASSERT(r, SK_ColorBLUE ==
  190. rootOut->compoundDrawable()->paintDrawable()->paint().getColor());
  191. REPORTER_ASSERT(r, 9 == rootOut->intDrawable()->a());
  192. REPORTER_ASSERT(r, 10 == rootOut->intDrawable()->b());
  193. REPORTER_ASSERT(r, 11 == rootOut->intDrawable()->c());
  194. REPORTER_ASSERT(r, 12 == rootOut->intDrawable()->d());
  195. // Note that we can still recognize the generic drawable as an IntDrawable
  196. SkDrawable* generic = rootOut->drawable();
  197. REPORTER_ASSERT(r, !strcmp("IntDrawable", generic->getTypeName()));
  198. IntDrawable* integer = (IntDrawable*) generic;
  199. REPORTER_ASSERT(r, 1 == integer->a());
  200. REPORTER_ASSERT(r, 2 == integer->b());
  201. REPORTER_ASSERT(r, 3 == integer->c());
  202. REPORTER_ASSERT(r, 4 == integer->d());
  203. }
  204. DEF_TEST(FlattenRecordedDrawable, r) {
  205. // Record a set of canvas draw commands
  206. SkPictureRecorder recorder;
  207. SkCanvas* canvas = recorder.beginRecording(1000.0f, 1000.0f);
  208. SkPaint paint;
  209. paint.setColor(SK_ColorGREEN);
  210. canvas->drawPoint(42.0f, 17.0f, paint);
  211. paint.setColor(SK_ColorRED);
  212. canvas->drawPaint(paint);
  213. SkPaint textPaint;
  214. textPaint.setColor(SK_ColorBLUE);
  215. canvas->drawString("TEXT", 467.0f, 100.0f, SkFont(), textPaint);
  216. // Draw some drawables as well
  217. sk_sp<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4));
  218. sk_sp<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 11, 12, drawable.get()));
  219. canvas->drawDrawable(root.get(), 747.0f, 242.0f);
  220. sk_sp<PaintDrawable> paintDrawable(new PaintDrawable(paint));
  221. canvas->drawDrawable(paintDrawable.get(), 500.0, 500.0f);
  222. sk_sp<CompoundDrawable> comDrawable(new CompoundDrawable(13, 14, 15, 16, textPaint));
  223. canvas->drawDrawable(comDrawable.get(), 10.0f, 10.0f);
  224. // Serialize the recorded drawable
  225. sk_sp<SkDrawable> recordedDrawable = recorder.finishRecordingAsDrawable();
  226. SkBinaryWriteBuffer writeBuffer;
  227. writeBuffer.writeFlattenable(recordedDrawable.get());
  228. // Copy the contents of the write buffer into a read buffer
  229. sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten());
  230. writeBuffer.writeToMemory(data->writable_data());
  231. SkReadBuffer readBuffer(data->data(), data->size());
  232. // Deserialize and verify the drawable
  233. sk_sp<SkDrawable> out((SkDrawable*)readBuffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
  234. REPORTER_ASSERT(r, out);
  235. REPORTER_ASSERT(r, !strcmp("SkRecordedDrawable", out->getTypeName()));
  236. }
  237. // be sure these constructs compile, don't assert, and return null
  238. DEF_TEST(Flattenable_EmptyDeserialze, reporter) {
  239. auto data = SkData::MakeEmpty();
  240. #define test(name) REPORTER_ASSERT(reporter, !name::Deserialize(data->data(), data->size()))
  241. test(SkPathEffect);
  242. test(SkMaskFilter);
  243. test(SkShaderBase); // todo: make this just be shader!
  244. test(SkColorFilter);
  245. test(SkImageFilter);
  246. test(SkDrawLooper);
  247. #undef test
  248. }