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

#include "tests/Test.h"

#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Recorder.h"
#include "src/core/SkPipelineData.h"
#include "src/core/SkUniform.h"
#include "src/gpu/graphite/PipelineDataCache.h"
#include "src/gpu/graphite/RecorderPriv.h"

using namespace skgpu::graphite;

DEF_GRAPHITE_TEST_FOR_CONTEXTS(PipelineDataCacheTest, reporter, context) {
    std::unique_ptr<Recorder> recorder = context->makeRecorder();

    auto cache = recorder->priv().uniformDataCache();

    REPORTER_ASSERT(reporter, cache->count() == 0);

    static const int kSize = 16;

    // Add a new unique UDB
    static const char kMemory1[kSize] = {
            7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
    };
    SkUniformDataBlock udb1(SkSpan(kMemory1, kSize));
    const SkUniformDataBlock* id1;
    {
        id1 = cache->insert(udb1);
        REPORTER_ASSERT(reporter, SkToBool(id1));
        REPORTER_ASSERT(reporter, id1 != &udb1);  // must be a separate address
        REPORTER_ASSERT(reporter, *id1 == udb1);  // but equal contents

        REPORTER_ASSERT(reporter, cache->count() == 1);
    }

    // Try to add a duplicate UDB
    {
        static const char kMemory2[kSize] = {
                7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
        };
        SkUniformDataBlock udb2(SkSpan(kMemory2, kSize));
        const SkUniformDataBlock* id2 = cache->insert(udb2);
        REPORTER_ASSERT(reporter, id2 == id1);

        REPORTER_ASSERT(reporter, cache->count() == 1);
    }

    // Add a second new unique UDB
    {
        static const char kMemory3[kSize] = {
                6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
        };
        SkUniformDataBlock udb3(SkSpan(kMemory3, kSize));
        const SkUniformDataBlock* id3 = cache->insert(udb3);
        REPORTER_ASSERT(reporter, SkToBool(id3));
        REPORTER_ASSERT(reporter, id3 != id1);
        REPORTER_ASSERT(reporter, *id3 == udb3);

        REPORTER_ASSERT(reporter, cache->count() == 2);
    }

    // TODO(robertphillips): expand this test to exercise all the UDB comparison failure modes
}
