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

// This is a GPU-backend specific test. It relies on static intializers to work

#include "SkTypes.h"

#if SK_SUPPORT_GPU && defined(SK_VULKAN)

#include "GrContextPriv.h"
#include "GrContextFactory.h"
#include "GrTest.h"
#include "Test.h"
#include "vk/GrVkGpu.h"

using sk_gpu_test::GrContextFactory;

void subheap_test(skiatest::Reporter* reporter, GrContext* context) {
    GrVkGpu* gpu = static_cast<GrVkGpu*>(context->contextPriv().getGpu());

    // memtype doesn't matter, we're just testing the suballocation algorithm so we'll use 0
    GrVkSubHeap heap(gpu, 0, 0, 64 * 1024, 32);
    GrVkAlloc alloc0, alloc1, alloc2, alloc3;
    // test full allocation and free
    REPORTER_ASSERT(reporter, heap.alloc(64 * 1024, &alloc0));
    REPORTER_ASSERT(reporter, alloc0.fOffset == 0);
    REPORTER_ASSERT(reporter, alloc0.fSize == 64 * 1024);
    REPORTER_ASSERT(reporter, heap.freeSize() == 0 && heap.largestBlockSize() == 0);
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.freeSize() == 64*1024 && heap.largestBlockSize() == 64 * 1024);

    // now let's suballoc some memory
    REPORTER_ASSERT(reporter, heap.alloc(16 * 1024, &alloc0));
    REPORTER_ASSERT(reporter, heap.alloc(23 * 1024, &alloc1));
    REPORTER_ASSERT(reporter, heap.alloc(18 * 1024, &alloc2));
    REPORTER_ASSERT(reporter, heap.freeSize() == 7 * 1024 && heap.largestBlockSize() == 7 * 1024);
    // free lone block
    heap.free(alloc1);
    REPORTER_ASSERT(reporter, heap.freeSize() == 30 * 1024 && heap.largestBlockSize() == 23 * 1024);
    // allocate into smallest free block
    REPORTER_ASSERT(reporter, heap.alloc(6 * 1024, &alloc3));
    REPORTER_ASSERT(reporter, heap.freeSize() == 24 * 1024 && heap.largestBlockSize() == 23 * 1024);
    // allocate into exact size free block
    REPORTER_ASSERT(reporter, heap.alloc(23 * 1024, &alloc1));
    REPORTER_ASSERT(reporter, heap.freeSize() == 1 * 1024 && heap.largestBlockSize() == 1 * 1024);
    // free lone block
    heap.free(alloc2);
    REPORTER_ASSERT(reporter, heap.freeSize() == 19 * 1024 && heap.largestBlockSize() == 18 * 1024);
    // free and merge with preceding block and following
    heap.free(alloc3);
    REPORTER_ASSERT(reporter, heap.freeSize() == 25 * 1024 && heap.largestBlockSize() == 25 * 1024);
    // free and merge with following block
    heap.free(alloc1);
    REPORTER_ASSERT(reporter, heap.freeSize() == 48 * 1024 && heap.largestBlockSize() == 48 * 1024);
    // free starting block and merge with following
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.freeSize() == 64 * 1024 && heap.largestBlockSize() == 64 * 1024);

    // realloc
    REPORTER_ASSERT(reporter, heap.alloc(4 * 1024, &alloc0));
    REPORTER_ASSERT(reporter, heap.alloc(35 * 1024, &alloc1));
    REPORTER_ASSERT(reporter, heap.alloc(10 * 1024, &alloc2));
    REPORTER_ASSERT(reporter, heap.freeSize() == 15 * 1024 && heap.largestBlockSize() == 15 * 1024);
    // free starting block and merge with following
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.freeSize() == 19 * 1024 && heap.largestBlockSize() == 15 * 1024);
    // free block and merge with preceding
    heap.free(alloc1);
    REPORTER_ASSERT(reporter, heap.freeSize() == 54 * 1024 && heap.largestBlockSize() == 39 * 1024);
    // free block and merge with preceding and following
    heap.free(alloc2);
    REPORTER_ASSERT(reporter, heap.freeSize() == 64 * 1024 && heap.largestBlockSize() == 64 * 1024);

    // fragment
    REPORTER_ASSERT(reporter, heap.alloc(19 * 1024, &alloc0));
    REPORTER_ASSERT(reporter, heap.alloc(5 * 1024, &alloc1));
    REPORTER_ASSERT(reporter, heap.alloc(15 * 1024, &alloc2));
    REPORTER_ASSERT(reporter, heap.alloc(3 * 1024, &alloc3));
    REPORTER_ASSERT(reporter, heap.freeSize() == 22 * 1024 && heap.largestBlockSize() == 22 * 1024);
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.freeSize() == 41 * 1024 && heap.largestBlockSize() == 22 * 1024);
    heap.free(alloc2);
    REPORTER_ASSERT(reporter, heap.freeSize() == 56 * 1024 && heap.largestBlockSize() == 22 * 1024);
    REPORTER_ASSERT(reporter, !heap.alloc(40 * 1024, &alloc0));
    heap.free(alloc3);
    REPORTER_ASSERT(reporter, heap.freeSize() == 59 * 1024 && heap.largestBlockSize() == 40 * 1024);
    REPORTER_ASSERT(reporter, heap.alloc(40 * 1024, &alloc0));
    REPORTER_ASSERT(reporter, heap.freeSize() == 19 * 1024 && heap.largestBlockSize() == 19 * 1024);
    heap.free(alloc1);
    REPORTER_ASSERT(reporter, heap.freeSize() == 24 * 1024 && heap.largestBlockSize() == 24 * 1024);
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.freeSize() == 64 * 1024 && heap.largestBlockSize() == 64 * 1024);

    // unaligned sizes
    REPORTER_ASSERT(reporter, heap.alloc(19 * 1024 - 31, &alloc0));
    REPORTER_ASSERT(reporter, heap.alloc(5 * 1024 - 5, &alloc1));
    REPORTER_ASSERT(reporter, heap.alloc(15 * 1024 - 19, &alloc2));
    REPORTER_ASSERT(reporter, heap.alloc(3 * 1024 - 3, &alloc3));
    REPORTER_ASSERT(reporter, heap.freeSize() == 22 * 1024 && heap.largestBlockSize() == 22 * 1024);
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.freeSize() == 41 * 1024 && heap.largestBlockSize() == 22 * 1024);
    heap.free(alloc2);
    REPORTER_ASSERT(reporter, heap.freeSize() == 56 * 1024 && heap.largestBlockSize() == 22 * 1024);
    REPORTER_ASSERT(reporter, !heap.alloc(40 * 1024, &alloc0));
    heap.free(alloc3);
    REPORTER_ASSERT(reporter, heap.freeSize() == 59 * 1024 && heap.largestBlockSize() == 40 * 1024);
    REPORTER_ASSERT(reporter, heap.alloc(40 * 1024, &alloc0));
    REPORTER_ASSERT(reporter, heap.freeSize() == 19 * 1024 && heap.largestBlockSize() == 19 * 1024);
    heap.free(alloc1);
    REPORTER_ASSERT(reporter, heap.freeSize() == 24 * 1024 && heap.largestBlockSize() == 24 * 1024);
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.freeSize() == 64 * 1024 && heap.largestBlockSize() == 64 * 1024);
}

void suballoc_test(skiatest::Reporter* reporter, GrContext* context) {
    GrVkGpu* gpu = static_cast<GrVkGpu*>(context->contextPriv().getGpu());

    // memtype/heap index don't matter, we're just testing the allocation algorithm so we'll use 0
    GrVkHeap heap(gpu, GrVkHeap::kSubAlloc_Strategy, 64 * 1024);
    GrVkAlloc alloc0, alloc1, alloc2, alloc3;
    const VkDeviceSize kAlignment = 16;
    const uint32_t kMemType = 0;
    const uint32_t kHeapIndex = 0;

    REPORTER_ASSERT(reporter, heap.allocSize() == 0 && heap.usedSize() == 0);

    // fragment allocations so we need to grow heap
    REPORTER_ASSERT(reporter, heap.alloc(19 * 1024 - 3, kAlignment, kMemType, kHeapIndex, &alloc0));
    REPORTER_ASSERT(reporter, heap.alloc(5 * 1024 - 9, kAlignment, kMemType, kHeapIndex, &alloc1));
    REPORTER_ASSERT(reporter, heap.alloc(15 * 1024 - 15, kAlignment, kMemType, kHeapIndex, &alloc2));
    REPORTER_ASSERT(reporter, heap.alloc(3 * 1024 - 6, kAlignment, kMemType, kHeapIndex, &alloc3));
    REPORTER_ASSERT(reporter, heap.allocSize() == 64 * 1024 && heap.usedSize() == 42 * 1024);
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.allocSize() == 64 * 1024 && heap.usedSize() == 23 * 1024);
    heap.free(alloc2);
    REPORTER_ASSERT(reporter, heap.allocSize() == 64 * 1024 && heap.usedSize() == 8 * 1024);
    // we expect the heap to grow here
    REPORTER_ASSERT(reporter, heap.alloc(40 * 1024, kAlignment, kMemType, kHeapIndex, &alloc0));
    REPORTER_ASSERT(reporter, heap.allocSize() == 128 * 1024 && heap.usedSize() == 48 * 1024);
    heap.free(alloc3);
    REPORTER_ASSERT(reporter, heap.allocSize() == 128 * 1024 && heap.usedSize() == 45 * 1024);
    // heap should not grow here (first subheap has exactly enough room)
    REPORTER_ASSERT(reporter, heap.alloc(40 * 1024, kAlignment, kMemType, kHeapIndex, &alloc3));
    REPORTER_ASSERT(reporter, heap.allocSize() == 128 * 1024 && heap.usedSize() == 85 * 1024);
    // heap should not grow here (second subheap has room)
    REPORTER_ASSERT(reporter, heap.alloc(22 * 1024, kAlignment, kMemType, kHeapIndex, &alloc2));
    REPORTER_ASSERT(reporter, heap.allocSize() == 128 * 1024 && heap.usedSize() == 107 * 1024);
    heap.free(alloc1);
    REPORTER_ASSERT(reporter, heap.allocSize() == 128 * 1024 && heap.usedSize() == 102 * 1024);
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.allocSize() == 128 * 1024 && heap.usedSize() == 62 * 1024);
    heap.free(alloc2);
    REPORTER_ASSERT(reporter, heap.allocSize() == 128 * 1024 && heap.usedSize() == 40 * 1024);
    heap.free(alloc3);
    REPORTER_ASSERT(reporter, heap.allocSize() == 128 * 1024 && heap.usedSize() == 0 * 1024);
    // heap should not grow here (allocating more than subheap size)
    REPORTER_ASSERT(reporter, heap.alloc(128 * 1024, kAlignment, kMemType, kHeapIndex, &alloc0));
    REPORTER_ASSERT(reporter, 0 == alloc0.fSize);
    REPORTER_ASSERT(reporter, heap.allocSize() == 128 * 1024 && heap.usedSize() == 0 * 1024);
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.alloc(24 * 1024, kAlignment, kMemType, kHeapIndex, &alloc0));
    REPORTER_ASSERT(reporter, heap.allocSize() == 128 * 1024 && heap.usedSize() == 24 * 1024);
    // heap should alloc a new subheap because the memory type is different
    REPORTER_ASSERT(reporter, heap.alloc(24 * 1024, kAlignment, kMemType+1, kHeapIndex, &alloc1));
    REPORTER_ASSERT(reporter, heap.allocSize() == 192 * 1024 && heap.usedSize() == 48 * 1024);
    // heap should alloc a new subheap because the alignment is different
    REPORTER_ASSERT(reporter, heap.alloc(24 * 1024, 128, kMemType, kHeapIndex, &alloc2));
    REPORTER_ASSERT(reporter, heap.allocSize() == 256 * 1024 && heap.usedSize() == 72 * 1024);
    heap.free(alloc2);
    heap.free(alloc0);
    heap.free(alloc1);
    REPORTER_ASSERT(reporter, heap.allocSize() == 256 * 1024 && heap.usedSize() == 0 * 1024);
}

void singlealloc_test(skiatest::Reporter* reporter, GrContext* context) {
    GrVkGpu* gpu = static_cast<GrVkGpu*>(context->contextPriv().getGpu());

    // memtype/heap index don't matter, we're just testing the allocation algorithm so we'll use 0
    GrVkHeap heap(gpu, GrVkHeap::kSingleAlloc_Strategy, 64 * 1024);
    GrVkAlloc alloc0, alloc1, alloc2, alloc3;
    const VkDeviceSize kAlignment = 64;
    const uint32_t kMemType = 0;
    const uint32_t kHeapIndex = 0;

    REPORTER_ASSERT(reporter, heap.allocSize() == 0 && heap.usedSize() == 0);

    // make a few allocations
    REPORTER_ASSERT(reporter, heap.alloc(49 * 1024 - 3, kAlignment, kMemType, kHeapIndex, &alloc0));
    REPORTER_ASSERT(reporter, heap.alloc(5 * 1024 - 37, kAlignment, kMemType, kHeapIndex, &alloc1));
    REPORTER_ASSERT(reporter, heap.alloc(15 * 1024 - 11, kAlignment, kMemType, kHeapIndex, &alloc2));
    REPORTER_ASSERT(reporter, heap.alloc(3 * 1024 - 29, kAlignment, kMemType, kHeapIndex, &alloc3));
    REPORTER_ASSERT(reporter, heap.allocSize() == 72 * 1024 && heap.usedSize() == 72 * 1024);
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.allocSize() == 72 * 1024 && heap.usedSize() == 23 * 1024);
    heap.free(alloc2);
    REPORTER_ASSERT(reporter, heap.allocSize() == 72 * 1024 && heap.usedSize() == 8 * 1024);
    // heap should not grow here (first subheap has room)
    REPORTER_ASSERT(reporter, heap.alloc(40 * 1024, kAlignment, kMemType, kHeapIndex, &alloc0));
    REPORTER_ASSERT(reporter, heap.allocSize() == 72 * 1024 && heap.usedSize() == 48 * 1024);
    heap.free(alloc3);
    REPORTER_ASSERT(reporter, heap.allocSize() == 72 * 1024 && heap.usedSize() == 45 * 1024);
    // check for exact fit -- heap should not grow here (third subheap has room)
    REPORTER_ASSERT(reporter, heap.alloc(15 * 1024 - 63, kAlignment, kMemType, kHeapIndex, &alloc2));
    REPORTER_ASSERT(reporter, heap.allocSize() == 72 * 1024 && heap.usedSize() == 60 * 1024);
    heap.free(alloc2);
    REPORTER_ASSERT(reporter, heap.allocSize() == 72 * 1024 && heap.usedSize() == 45 * 1024);
    // heap should grow here (no subheap has room)
    REPORTER_ASSERT(reporter, heap.alloc(40 * 1024, kAlignment, kMemType, kHeapIndex, &alloc3));
    REPORTER_ASSERT(reporter, heap.allocSize() == 112 * 1024 && heap.usedSize() == 85 * 1024);
    heap.free(alloc1);
    REPORTER_ASSERT(reporter, heap.allocSize() == 112 * 1024 && heap.usedSize() == 80 * 1024);
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.allocSize() == 112 * 1024 && heap.usedSize() == 40 * 1024);
    heap.free(alloc3);
    REPORTER_ASSERT(reporter, heap.allocSize() == 112 * 1024 && heap.usedSize() == 0 * 1024);
    REPORTER_ASSERT(reporter, heap.alloc(24 * 1024, kAlignment, kMemType, kHeapIndex, &alloc0));
    REPORTER_ASSERT(reporter, heap.allocSize() == 112 * 1024 && heap.usedSize() == 24 * 1024);
    // heap should alloc a new subheap because the memory type is different
    REPORTER_ASSERT(reporter, heap.alloc(24 * 1024, kAlignment, kMemType + 1, kHeapIndex, &alloc1));
    REPORTER_ASSERT(reporter, heap.allocSize() == 136 * 1024 && heap.usedSize() == 48 * 1024);
    // heap should alloc a new subheap because the alignment is different
    REPORTER_ASSERT(reporter, heap.alloc(24 * 1024, 128, kMemType, kHeapIndex, &alloc2));
    REPORTER_ASSERT(reporter, heap.allocSize() == 160 * 1024 && heap.usedSize() == 72 * 1024);
    heap.free(alloc1);
    heap.free(alloc2);
    heap.free(alloc0);
    REPORTER_ASSERT(reporter, heap.allocSize() == 160 * 1024 && heap.usedSize() == 0 * 1024);
}

DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkHeapTests, reporter, ctxInfo) {
    subheap_test(reporter, ctxInfo.grContext());
    suballoc_test(reporter, ctxInfo.grContext());
    singlealloc_test(reporter, ctxInfo.grContext());
}

#endif
