| Index: tests/SerializeDrawableTest.cpp
|
| diff --git a/tests/SerializeDrawableTest.cpp b/tests/SerializeDrawableTest.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6257920e1a218a426ba76c21f6952867fb3e9014
|
| --- /dev/null
|
| +++ b/tests/SerializeDrawableTest.cpp
|
| @@ -0,0 +1,368 @@
|
| +/*
|
| + * 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
|
| + * 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());
|
| + */
|
| +}
|
| +
|
| +SkFlattenable* custom_create_proc(SkReadBuffer& buffer) {
|
| + SkAutoTUnref<SkFlattenable> drawable(IntDrawable::CreateProc(buffer));
|
| + IntDrawable* intDrawable = (IntDrawable*) drawable.get();
|
| + return new IntDrawable(intDrawable->a() + 1, intDrawable->b() + 1, intDrawable->c() + 1,
|
| + intDrawable->d() + 1);
|
| +}
|
| +
|
| +DEF_TEST(SerializeCustomDrawable, r) {
|
| + register_test_drawables_once();
|
| +
|
| + // Create and serialize the test drawable
|
| + SkAutoTUnref<SkDrawable> drawable(new IntDrawable(1, 2, 3, 4));
|
| + SkWriteBuffer writeBuffer;
|
| + writeBuffer.writeFlattenable(drawable);
|
| +
|
| + // 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());
|
| +
|
| + // Register a custom factory with the read buffer
|
| + readBuffer.setCustomFactory("IntDrawable", &custom_create_proc);
|
| +
|
| + // Deserialize and verify the drawable
|
| + SkAutoTUnref<IntDrawable> out((IntDrawable*)
|
| + readBuffer.readFlattenable(SkFlattenable::kSkDrawable_Type));
|
| + REPORTER_ASSERT(r, out);
|
| + REPORTER_ASSERT(r, 2 == out->a());
|
| + REPORTER_ASSERT(r, 3 == out->b());
|
| + REPORTER_ASSERT(r, 4 == out->c());
|
| + REPORTER_ASSERT(r, 5 == out->d());
|
| +}
|
|
|