16573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org/*
26573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org * Copyright 2014 Google Inc.
36573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org *
46573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
56573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org * found in the LICENSE file.
66573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org */
76573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
86573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org#include "SkDeque.h"
96573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org#include "SkLayerRasterizer.h"
106573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org#include "SkPaint.h"
116573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org#include "SkRasterizer.h"
126573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org#include "Test.h"
136573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
146573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.orgclass SkReadBuffer;
156573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
166573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org// Dummy class to place on a paint just to ensure the paint's destructor
176573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org// is called.
186573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org// ONLY to be used by LayerRasterizer_destructor, since other tests may
196573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org// be run in a separate thread, and this class is not threadsafe.
206573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.orgclass DummyRasterizer : public SkRasterizer {
216573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.orgpublic:
226573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    DummyRasterizer()
236573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        : INHERITED()
246573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    {
256573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        // Not threadsafe. Only used in one thread.
266573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        gCount++;
276573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    }
286573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
296573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    ~DummyRasterizer() {
306573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        // Not threadsafe. Only used in one thread.
316573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        gCount--;
326573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    }
336573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
346573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    static int GetCount() { return gCount; }
356573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
366573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(DummyRasterizer)
376573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
386573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.orgprivate:
396573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    DummyRasterizer(SkReadBuffer&) {}
406573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
416573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    static int gCount;
426573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
436573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    typedef SkRasterizer INHERITED;
446573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org};
456573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
466573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.orgint DummyRasterizer::gCount;
476573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
486573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org// Check to make sure that the SkPaint in the layer has its destructor called.
496573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.orgDEF_TEST(LayerRasterizer_destructor, reporter) {
506573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    {
516573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        SkPaint paint;
526573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        paint.setRasterizer(SkNEW(DummyRasterizer))->unref();
536573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        REPORTER_ASSERT(reporter, DummyRasterizer::GetCount() == 1);
546573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
556573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        SkLayerRasterizer::Builder builder;
566573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        builder.addLayer(paint);
576573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    }
586573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    REPORTER_ASSERT(reporter, DummyRasterizer::GetCount() == 0);
596573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org}
606573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
616573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.orgclass LayerRasterizerTester {
626573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.orgpublic:
636573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    static int CountLayers(const SkLayerRasterizer& layerRasterizer) {
646573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        return layerRasterizer.fLayers->count();
656573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    }
666573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
676573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    static const SkDeque& GetLayers(const SkLayerRasterizer& layerRasterizer) {
686573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        return *layerRasterizer.fLayers;
696573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    }
706573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org};
716573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
726573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org// MUST stay in sync with definition of SkLayerRasterizer_Rec in SkLayerRasterizer.cpp.
736573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.orgstruct SkLayerRasterizer_Rec {
746573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    SkPaint     fPaint;
756573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    SkVector    fOffset;
766573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org};
776573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
786573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.orgstatic bool equals(const SkLayerRasterizer_Rec& rec1, const SkLayerRasterizer_Rec& rec2) {
796573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    return rec1.fPaint == rec2.fPaint && rec1.fOffset == rec2.fOffset;
806573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org}
816573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
826573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.orgDEF_TEST(LayerRasterizer_copy, reporter) {
836573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    SkLayerRasterizer::Builder builder;
8465044bfe021e9c0023d78080583e9acb3bdb5ce7scroggo    REPORTER_ASSERT(reporter, NULL == builder.snapshotRasterizer());
856573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    SkPaint paint;
866573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    // Create a bunch of paints with different flags.
876573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    for (uint32_t flags = 0x01; flags < SkPaint::kAllFlags; flags <<= 1) {
886573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        paint.setFlags(flags);
8955c9b4e9f645bba196b142ae7783ac61822adfd7commit-bot@chromium.org        builder.addLayer(paint, static_cast<SkScalar>(flags), static_cast<SkScalar>(flags));
906573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    }
916573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
926573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    // Create a layer rasterizer with all the existing layers.
936573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    SkAutoTUnref<SkLayerRasterizer> firstCopy(builder.snapshotRasterizer());
946573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
956573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    // Add one more layer.
966573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    paint.setFlags(SkPaint::kAllFlags);
976573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    builder.addLayer(paint);
986573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
996573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    SkAutoTUnref<SkLayerRasterizer> oneLarger(builder.snapshotRasterizer());
1006573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    SkAutoTUnref<SkLayerRasterizer> detached(builder.detachRasterizer());
1016573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
1026573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    // Check the counts for consistency.
1036573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    const int largerCount = LayerRasterizerTester::CountLayers(*oneLarger.get());
1046573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    const int smallerCount = LayerRasterizerTester::CountLayers(*firstCopy.get());
1056573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    REPORTER_ASSERT(reporter, largerCount == LayerRasterizerTester::CountLayers(*detached.get()));
1066573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    REPORTER_ASSERT(reporter, smallerCount == largerCount - 1);
1076573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
1086573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    const SkLayerRasterizer_Rec* recFirstCopy = NULL;
1096573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    const SkLayerRasterizer_Rec* recOneLarger = NULL;
1106573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    const SkLayerRasterizer_Rec* recDetached = NULL;
1116573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
1126573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    const SkDeque& layersFirstCopy = LayerRasterizerTester::GetLayers(*firstCopy.get());
1136573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    const SkDeque& layersOneLarger = LayerRasterizerTester::GetLayers(*oneLarger.get());
1146573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    const SkDeque& layersDetached = LayerRasterizerTester::GetLayers(*detached.get());
1156573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
1166573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    // Ensure that our version of SkLayerRasterizer_Rec is the same as the one in
1176573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    // SkLayerRasterizer.cpp - or at least the same size. If the order were switched, we
1186573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    // would fail the test elsewhere.
1196573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    REPORTER_ASSERT(reporter, layersFirstCopy.elemSize() == sizeof(SkLayerRasterizer_Rec));
1206573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    REPORTER_ASSERT(reporter, layersOneLarger.elemSize() == sizeof(SkLayerRasterizer_Rec));
1216573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    REPORTER_ASSERT(reporter, layersDetached.elemSize() == sizeof(SkLayerRasterizer_Rec));
1226573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
1236573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    SkDeque::F2BIter iterFirstCopy(layersFirstCopy);
1246573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    SkDeque::F2BIter iterOneLarger(layersOneLarger);
1256573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    SkDeque::F2BIter iterDetached(layersDetached);
1266573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
1276573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    for (int i = 0; i < largerCount; ++i) {
1286573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        recFirstCopy = static_cast<const SkLayerRasterizer_Rec*>(iterFirstCopy.next());
1296573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        recOneLarger = static_cast<const SkLayerRasterizer_Rec*>(iterOneLarger.next());
1306573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        recDetached  = static_cast<const SkLayerRasterizer_Rec*>(iterDetached.next());
1316573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org
1326573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        REPORTER_ASSERT(reporter, equals(*recOneLarger, *recDetached));
1336573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        if (smallerCount == i) {
1346573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org            REPORTER_ASSERT(reporter, recFirstCopy == NULL);
1356573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        } else {
1366573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org            REPORTER_ASSERT(reporter, equals(*recFirstCopy, *recOneLarger));
1376573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org        }
1386573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org    }
1396573ce70e609f19923cea401d4ca3ea1528a78f1commit-bot@chromium.org}
14065044bfe021e9c0023d78080583e9acb3bdb5ce7scroggo
14165044bfe021e9c0023d78080583e9acb3bdb5ce7scroggoDEF_TEST(LayerRasterizer_detachEmpty, reporter) {
14265044bfe021e9c0023d78080583e9acb3bdb5ce7scroggo    SkLayerRasterizer::Builder builder;
14365044bfe021e9c0023d78080583e9acb3bdb5ce7scroggo    REPORTER_ASSERT(reporter, NULL == builder.detachRasterizer());
14465044bfe021e9c0023d78080583e9acb3bdb5ce7scroggo}
145