/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTileMode.h"
#include "src/core/SkPicturePriv.h"
#include "src/core/SkResourceCache.h"
#include "tests/Test.h"

#include <cstdint>
#include <initializer_list>

// Test that the SkPictureShader cache is purged on shader deletion.
DEF_TEST(PictureShader_caching, reporter) {
    auto makePicture = [] () {
        SkPictureRecorder recorder;
        recorder.beginRecording(100, 100)->drawColor(SK_ColorGREEN);
        return recorder.finishRecordingAsPicture();
    };

    sk_sp<SkPicture> picture = makePicture();
    REPORTER_ASSERT(reporter, picture->unique());

    sk_sp<SkSurface> surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(100, 100));

    {
        SkPaint paint;
        paint.setShader(picture->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                            SkFilterMode::kNearest));
        surface->getCanvas()->drawPaint(paint);

        // We should have about 3 refs by now: local + shader + shader cache.
        REPORTER_ASSERT(reporter, !picture->unique());
    }

    // Draw another picture shader to have a chance to purge.
    {
        SkPaint paint;
        paint.setShader(makePicture()->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                                  SkFilterMode::kNearest));
        surface->getCanvas()->drawPaint(paint);

    }

    // All but the local ref should be gone now.
    REPORTER_ASSERT(reporter, picture->unique());
}

/*
 *  Check caching of picture-shaders
 *  - we do cache the underlying image (i.e. there is a cache entry)
 *  - there is only 1 entry, even with differing tile modes
 *  - after deleting the picture, the cache entry is purged
 */
DEF_TEST(PictureShader_caching2, reporter) {
    auto picture = []() {
        SkPictureRecorder recorder;
        recorder.beginRecording(100, 100)->drawColor(SK_ColorGREEN);
        return recorder.finishRecordingAsPicture();
    }();
    REPORTER_ASSERT(reporter, picture->unique());

    struct Data {
        uint64_t sharedID;
        int counter;
    } data = {
        SkPicturePriv::MakeSharedID(picture->uniqueID()),
        0,
    };

    auto counter = [](const SkResourceCache::Rec& rec, void* dataPtr) {
        if (rec.getKey().getSharedID() == ((Data*)dataPtr)->sharedID) {
            ((Data*)dataPtr)->counter += 1;
        }
    };

    SkResourceCache::VisitAll(counter, &data);
    REPORTER_ASSERT(reporter, data.counter == 0);

    // Draw with a view variants of picture-shaders that all use the same picture.
    // Only expect 1 cache entry for all (since same CTM for all).
    sk_sp<SkSurface> surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(100, 100));
    for (SkTileMode m : {
        SkTileMode::kClamp, SkTileMode::kRepeat, SkTileMode::kRepeat, SkTileMode::kDecal
    }) {
        SkPaint paint;
        paint.setShader(picture->makeShader(m, m, SkFilterMode::kNearest));
        surface->getCanvas()->drawPaint(paint);
    }

    // Don't expect any additional refs on the picture
    REPORTER_ASSERT(reporter, picture->unique());

    // Check that we did cache something, but only 1 thing
    data.counter = 0;
    SkResourceCache::VisitAll(counter, &data);
    REPORTER_ASSERT(reporter, data.counter == 1);

    // Now delete the picture, and check the we purge the cache entry

    picture.reset();
    SkResourceCache::CheckMessages();

    data.counter = 0;
    SkResourceCache::VisitAll(counter, &data);
    REPORTER_ASSERT(reporter, data.counter == 0);
}
