Chromium Code Reviews| Index: tests/SerializeDrawableTest.cpp |
| diff --git a/tests/SerializeDrawableTest.cpp b/tests/SerializeDrawableTest.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..7ffcedebb9187cc7fe0267d03a344d207b886681 |
| --- /dev/null |
| +++ b/tests/SerializeDrawableTest.cpp |
| @@ -0,0 +1,335 @@ |
| +/* |
| + * Copyright 2016 Google Inc. |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| +#include "SkCanvas.h" |
| +#include "SkDrawable.h" |
| +#include "SkOnce.h" |
| +#include "SkPictureRecorder.h" |
| +#include "SkReadBuffer.h" |
| +#include "SkRect.h" |
| +#include "SkStream.h" |
| +#include "SkWriteBuffer.h" |
| +#include "Test.h" |
| + |
| +class IntDrawable : public SkDrawable { |
| +public: |
| + IntDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d) |
| + : fA(a) |
| + , fB(b) |
| + , fC(c) |
| + , fD(d) |
| + {} |
| + |
| + void flatten(SkWriteBuffer& buffer) const override { |
| + buffer.writeUInt(fA); |
| + buffer.writeUInt(fB); |
| + buffer.writeUInt(fC); |
| + buffer.writeUInt(fD); |
| + } |
| + |
| + static SkFlattenable* CreateProc(SkReadBuffer& buffer) { |
| + uint32_t a = buffer.readUInt(); |
| + uint32_t b = buffer.readUInt(); |
| + uint32_t c = buffer.readUInt(); |
| + uint32_t d = buffer.readUInt(); |
| + return new IntDrawable(a, b, c, d); |
| + } |
| + |
| + Factory getFactory() const override { return CreateProc; } |
| + |
| + uint32_t a() const { return fA; } |
| + uint32_t b() const { return fB; } |
| + uint32_t c() const { return fC; } |
| + uint32_t d() const { return fD; } |
| + |
| +protected: |
| + SkRect onGetBounds() override { return SkRect::MakeEmpty(); } |
| + void onDraw(SkCanvas*) override {} |
| + |
| +private: |
| + uint32_t fA; |
| + uint32_t fB; |
| + uint32_t fC; |
| + uint32_t fD; |
| +}; |
| + |
| +class PaintDrawable : public SkDrawable { |
| +public: |
| + PaintDrawable(const SkPaint& paint) |
| + : fPaint(paint) |
| + {} |
| + |
| + void flatten(SkWriteBuffer& buffer) const override { |
| + buffer.writePaint(fPaint); |
| + } |
| + |
| + static SkFlattenable* CreateProc(SkReadBuffer& buffer) { |
| + SkPaint paint; |
| + buffer.readPaint(&paint); |
| + return new PaintDrawable(paint); |
| + } |
| + |
| + Factory getFactory() const override { return CreateProc; } |
| + |
| + const SkPaint& paint() const { return fPaint; } |
| + |
| +protected: |
| + SkRect onGetBounds() override { return SkRect::MakeEmpty(); } |
| + void onDraw(SkCanvas*) override {} |
| + |
| +private: |
| + SkPaint fPaint; |
| +}; |
| + |
| +class CompoundDrawable : public SkDrawable { |
| +public: |
| + CompoundDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPaint& paint) |
| + : fIntDrawable(new IntDrawable(a, b, c, d)) |
| + , fPaintDrawable(new PaintDrawable(paint)) |
| + {} |
| + |
| + CompoundDrawable(IntDrawable* intDrawable, PaintDrawable* paintDrawable) |
| + : fIntDrawable(SkRef(intDrawable)) |
| + , fPaintDrawable(SkRef(paintDrawable)) |
| + {} |
| + |
| + void flatten(SkWriteBuffer& buffer) const override { |
| + buffer.writeFlattenable(fIntDrawable); |
| + buffer.writeFlattenable(fPaintDrawable); |
| + } |
| + |
| + static SkFlattenable* CreateProc(SkReadBuffer& buffer) { |
| + SkAutoTUnref<SkFlattenable> intDrawable( |
| + buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| + SkASSERT(intDrawable); |
| + SkASSERT(!strcmp("IntDrawable", intDrawable->getTypeName())); |
| + |
| + SkAutoTUnref<SkFlattenable> paintDrawable( |
| + buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| + SkASSERT(paintDrawable); |
| + SkASSERT(!strcmp("PaintDrawable", paintDrawable->getTypeName())); |
| + |
| + return new CompoundDrawable((IntDrawable*) intDrawable.get(), |
| + (PaintDrawable*) paintDrawable.get()); |
| + } |
| + |
| + Factory getFactory() const override { return CreateProc; } |
| + |
| + IntDrawable* intDrawable() const { return fIntDrawable; } |
| + PaintDrawable* paintDrawable() const { return fPaintDrawable; } |
| + |
| +protected: |
| + SkRect onGetBounds() override { return SkRect::MakeEmpty(); } |
| + void onDraw(SkCanvas*) override {} |
| + |
| +private: |
| + SkAutoTUnref<IntDrawable> fIntDrawable; |
| + SkAutoTUnref<PaintDrawable> fPaintDrawable; |
| +}; |
| + |
| +class RootDrawable : public SkDrawable { |
| +public: |
| + RootDrawable(uint32_t a, uint32_t b, uint32_t c, uint32_t d, const SkPaint& paint, |
| + uint32_t e, uint32_t f, uint32_t g, uint32_t h, SkDrawable* drawable) |
| + : fCompoundDrawable(new CompoundDrawable(a, b, c, d, paint)) |
| + , fIntDrawable(new IntDrawable(e, f, g, h)) |
| + , fDrawable(SkRef(drawable)) |
| + {} |
| + |
| + RootDrawable(CompoundDrawable* compoundDrawable, IntDrawable* intDrawable, |
| + SkDrawable* drawable) |
| + : fCompoundDrawable(SkRef(compoundDrawable)) |
| + , fIntDrawable(SkRef(intDrawable)) |
| + , fDrawable(SkRef(drawable)) |
| + {} |
| + |
| + void flatten(SkWriteBuffer& buffer) const override { |
| + buffer.writeFlattenable(fCompoundDrawable); |
| + buffer.writeFlattenable(fIntDrawable); |
| + buffer.writeFlattenable(fDrawable); |
| + } |
| + |
| + static SkFlattenable* CreateProc(SkReadBuffer& buffer) { |
| + SkAutoTUnref<SkFlattenable> compoundDrawable( |
| + buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| + SkASSERT(compoundDrawable); |
| + SkASSERT(!strcmp("CompoundDrawable", compoundDrawable->getTypeName())); |
| + |
| + SkAutoTUnref<SkFlattenable> intDrawable( |
| + buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| + SkASSERT(intDrawable); |
| + SkASSERT(!strcmp("IntDrawable", intDrawable->getTypeName())); |
| + |
| + SkAutoTUnref<SkFlattenable> drawable( |
| + buffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| + SkASSERT(drawable); |
| + |
| + return new RootDrawable((CompoundDrawable*) compoundDrawable.get(), |
| + (IntDrawable*) intDrawable.get(), |
| + (SkDrawable*) drawable.get()); |
| + } |
| + |
| + Factory getFactory() const override { return CreateProc; } |
| + |
| + CompoundDrawable* compoundDrawable() const { return fCompoundDrawable; } |
| + IntDrawable* intDrawable() const { return fIntDrawable; } |
| + SkDrawable* drawable() const { return fDrawable; } |
| + |
| +protected: |
| + SkRect onGetBounds() override { return SkRect::MakeEmpty(); } |
| + void onDraw(SkCanvas*) override {} |
| + |
| +private: |
| + SkAutoTUnref<CompoundDrawable> fCompoundDrawable; |
| + SkAutoTUnref<IntDrawable> fIntDrawable; |
| + SkAutoTUnref<SkDrawable> fDrawable; |
| +}; |
| + |
| +static void register_test_drawables() { |
| + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(IntDrawable) |
| + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(PaintDrawable) |
| + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(CompoundDrawable) |
| + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(RootDrawable) |
| +} |
| + |
| +SK_DECLARE_STATIC_ONCE(gOnce); |
| +static void register_test_drawables_once() { |
| + SkOnce(&gOnce, register_test_drawables); |
| +} |
| + |
| +DEF_TEST(SerializeDrawable, r) { |
| + register_test_drawables_once(); |
| + |
| + // Create and serialize the test drawable |
| + SkAutoTUnref<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4)); |
| + SkPaint paint; |
| + paint.setColor(SK_ColorBLUE); |
| + SkAutoTUnref<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 11, 12, drawable)); |
| + SkWriteBuffer writeBuffer; |
| + writeBuffer.writeFlattenable(root); |
| + |
| + // Copy the contents of the write buffer into a read buffer |
| + sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten()); |
| + writeBuffer.writeToMemory(data->writable_data()); |
| + SkReadBuffer readBuffer(data->data(), data->size()); |
| + |
| + // Deserialize and verify the drawable |
| + SkAutoTUnref<SkDrawable> out((SkDrawable*) |
| + readBuffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| + REPORTER_ASSERT(r, out); |
| + REPORTER_ASSERT(r, !strcmp("RootDrawable", out->getTypeName())); |
| + |
| + RootDrawable* rootOut = (RootDrawable*) out.get(); |
| + REPORTER_ASSERT(r, 5 == rootOut->compoundDrawable()->intDrawable()->a()); |
| + REPORTER_ASSERT(r, 6 == rootOut->compoundDrawable()->intDrawable()->b()); |
| + REPORTER_ASSERT(r, 7 == rootOut->compoundDrawable()->intDrawable()->c()); |
| + REPORTER_ASSERT(r, 8 == rootOut->compoundDrawable()->intDrawable()->d()); |
| + REPORTER_ASSERT(r, SK_ColorBLUE == |
| + rootOut->compoundDrawable()->paintDrawable()->paint().getColor()); |
| + REPORTER_ASSERT(r, 9 == rootOut->intDrawable()->a()); |
| + REPORTER_ASSERT(r, 10 == rootOut->intDrawable()->b()); |
| + REPORTER_ASSERT(r, 11 == rootOut->intDrawable()->c()); |
| + REPORTER_ASSERT(r, 12 == rootOut->intDrawable()->d()); |
| + |
| + // Note that we can still recognize the generic drawable as an IntDrawable |
| + SkDrawable* generic = rootOut->drawable(); |
| + REPORTER_ASSERT(r, !strcmp("IntDrawable", generic->getTypeName())); |
| + IntDrawable* integer = (IntDrawable*) generic; |
| + REPORTER_ASSERT(r, 1 == integer->a()); |
| + REPORTER_ASSERT(r, 2 == integer->b()); |
| + REPORTER_ASSERT(r, 3 == integer->c()); |
| + REPORTER_ASSERT(r, 4 == integer->d()); |
| +} |
| + |
| +DEF_TEST(SerializeRecordedDrawable, r) { |
| + register_test_drawables_once(); |
| + |
| + // Record a set of canvas draw commands |
| + SkPictureRecorder recorder; |
| + SkCanvas* canvas = recorder.beginRecording(1000.0f, 1000.0f); |
| + canvas->drawPoint(42.0f, 17.0f, SK_ColorGREEN); |
| + SkPaint paint; |
| + paint.setColor(SK_ColorRED); |
| + canvas->drawPaint(paint); |
| + SkPaint textPaint; |
| + textPaint.setColor(SK_ColorBLUE); |
| + canvas->drawText("TEXT", 354.0f, 467.0f, 100.0f, textPaint); |
| + |
| + // Draw some drawables as well |
| + SkAutoTUnref<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4)); |
| + SkAutoTUnref<RootDrawable> root(new RootDrawable(5, 6, 7, 8, paint, 9, 10, 11, 12, drawable)); |
| + canvas->drawDrawable(root, 747.0f, 242.0f); |
| + SkAutoTUnref<PaintDrawable> paintDrawable(new PaintDrawable(paint)); |
| + canvas->drawDrawable(paintDrawable, 500.0, 500.0f); |
| + SkAutoTUnref<CompoundDrawable> comDrawable(new CompoundDrawable(13, 14, 15, 16, textPaint)); |
| + canvas->drawDrawable(comDrawable, 10.0f, 10.0f); |
| + |
| + // Serialize the recorded drawable |
| + sk_sp<SkDrawable> recordedDrawable = recorder.finishRecordingAsDrawable(); |
| + SkWriteBuffer writeBuffer; |
| + writeBuffer.writeFlattenable(recordedDrawable.get()); |
| + |
| + // Copy the contents of the write buffer into a read buffer |
| + sk_sp<SkData> data = SkData::MakeUninitialized(writeBuffer.bytesWritten()); |
| + writeBuffer.writeToMemory(data->writable_data()); |
| + SkReadBuffer readBuffer(data->data(), data->size()); |
| + |
| + // Deserialize and verify the drawable |
| + SkAutoTUnref<SkDrawable> out((SkDrawable*) |
| + readBuffer.readFlattenable(SkFlattenable::kSkDrawable_Type)); |
| + REPORTER_ASSERT(r, out); |
| + REPORTER_ASSERT(r, !strcmp("SkRecordedDrawable", out->getTypeName())); |
| + |
| + /* |
| + * If we include SkRecordedDrawable.h and make all of the fields on |
|
msarett
2016/03/30 20:34:11
I'll remove this code block before submitting.
I
|
| + * SkRecordedDrawable public, the following tests should also pass. |
| + */ |
| + /* |
| + SkRecordedDrawable* outRD = (SkRecordedDrawable*) out.get(); |
| + SkRecordedDrawable* inRD = (SkRecordedDrawable*) recordedDrawable.get(); |
| + REPORTER_ASSERT(r, outRD->fBounds == inRD->fBounds); |
| + |
| + REPORTER_ASSERT(r, outRD->fDrawableList->count() == 3); |
| + REPORTER_ASSERT(r, outRD->fDrawableList->count() == inRD->fDrawableList->count()); |
| + SkDrawable* const* outArray = outRD->fDrawableList->begin(); |
| + |
| + // First the RootDrawable |
| + REPORTER_ASSERT(r, !strcmp("RootDrawable", outArray[0]->getTypeName())); |
| + RootDrawable* outRoot = (RootDrawable*) outArray[0]; |
| + REPORTER_ASSERT(r, 5 == outRoot->compoundDrawable()->intDrawable()->a()); |
| + REPORTER_ASSERT(r, 6 == outRoot->compoundDrawable()->intDrawable()->b()); |
| + REPORTER_ASSERT(r, 7 == outRoot->compoundDrawable()->intDrawable()->c()); |
| + REPORTER_ASSERT(r, 8 == outRoot->compoundDrawable()->intDrawable()->d()); |
| + REPORTER_ASSERT(r, SK_ColorRED == |
| + outRoot->compoundDrawable()->paintDrawable()->paint().getColor()); |
| + REPORTER_ASSERT(r, 9 == outRoot->intDrawable()->a()); |
| + REPORTER_ASSERT(r, 10 == outRoot->intDrawable()->b()); |
| + REPORTER_ASSERT(r, 11 == outRoot->intDrawable()->c()); |
| + REPORTER_ASSERT(r, 12 == outRoot->intDrawable()->d()); |
| + SkDrawable* generic = outRoot->drawable(); |
| + REPORTER_ASSERT(r, !strcmp("IntDrawable", generic->getTypeName())); |
| + IntDrawable* integer = (IntDrawable*) generic; |
| + REPORTER_ASSERT(r, 1 == integer->a()); |
| + REPORTER_ASSERT(r, 2 == integer->b()); |
| + REPORTER_ASSERT(r, 3 == integer->c()); |
| + REPORTER_ASSERT(r, 4 == integer->d()); |
| + |
| + // Next the PaintDrawable |
| + REPORTER_ASSERT(r, !strcmp("PaintDrawable", outArray[1]->getTypeName())); |
| + PaintDrawable* outPaint = (PaintDrawable*) outArray[1]; |
| + REPORTER_ASSERT(r, SK_ColorRED == outPaint->paint().getColor()); |
| + |
| + // Finally the CompoundDrawable |
| + REPORTER_ASSERT(r, !strcmp("CompoundDrawable", outArray[2]->getTypeName())); |
| + CompoundDrawable* outCompound = (CompoundDrawable*) outArray[2]; |
| + REPORTER_ASSERT(r, 13 == outCompound->intDrawable()->a()); |
| + REPORTER_ASSERT(r, 14 == outCompound->intDrawable()->b()); |
| + REPORTER_ASSERT(r, 15 == outCompound->intDrawable()->c()); |
| + REPORTER_ASSERT(r, 16 == outCompound->intDrawable()->d()); |
| + REPORTER_ASSERT(r, SK_ColorBLUE == outCompound->paintDrawable()->paint().getColor()); |
| + */ |
| +} |