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

#include "GrVkStencilAttachment.h"
#include "GrVkGpu.h"
#include "GrVkImage.h"
#include "GrVkImageView.h"
#include "GrVkUtil.h"

#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)

GrVkStencilAttachment::GrVkStencilAttachment(GrVkGpu* gpu,
                                             const Format& format,
                                             const GrVkImage::ImageDesc& desc,
                                             const GrVkImageInfo& info,
                                             const GrVkImageView* stencilView)
    : GrStencilAttachment(gpu, desc.fWidth, desc.fHeight, format.fStencilBits, desc.fSamples)
    , GrVkImage(info, GrVkImage::kNot_Wrapped)
    , fFormat(format)
    , fStencilView(stencilView) {
    this->registerWithCache(SkBudgeted::kYes);
    stencilView->ref();
}

GrVkStencilAttachment* GrVkStencilAttachment::Create(GrVkGpu* gpu,
                                                     int width,
                                                     int height,
                                                     int sampleCnt,
                                                     const Format& format) {
    GrVkImage::ImageDesc imageDesc;
    imageDesc.fImageType = VK_IMAGE_TYPE_2D;
    imageDesc.fFormat = format.fInternalFormat;
    imageDesc.fWidth = width;
    imageDesc.fHeight = height;
    imageDesc.fLevels = 1;
    imageDesc.fSamples = sampleCnt;
    imageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
    imageDesc.fUsageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
                            VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    imageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;

    GrVkImageInfo info;
    if (!GrVkImage::InitImageInfo(gpu, imageDesc, &info)) {
        return nullptr;
    }

    const GrVkImageView* imageView = GrVkImageView::Create(gpu, info.fImage,
                                                           format.fInternalFormat,
                                                           GrVkImageView::kStencil_Type, 1);
    if (!imageView) {
        GrVkImage::DestroyImageInfo(gpu, &info);
        return nullptr;
    }

    GrVkStencilAttachment* stencil = new GrVkStencilAttachment(gpu, format, imageDesc,
                                                               info, imageView);
    imageView->unref(gpu);

    return stencil;
}

GrVkStencilAttachment::~GrVkStencilAttachment() {
    // should have been released or abandoned first
    SkASSERT(!fStencilView);
}

size_t GrVkStencilAttachment::onGpuMemorySize() const {
    uint64_t size = this->width();
    size *= this->height();
    size *= fFormat.fTotalBits;
    size *= SkTMax(1,this->numSamples());
    return static_cast<size_t>(size / 8);
}

void GrVkStencilAttachment::onRelease() {
    GrVkGpu* gpu = this->getVkGpu();

    this->releaseImage(gpu);

    fStencilView->unref(gpu);
    fStencilView = nullptr;
    GrStencilAttachment::onRelease();
}

void GrVkStencilAttachment::onAbandon() {
    this->abandonImage();
    fStencilView->unrefAndAbandon();
    fStencilView = nullptr;
    GrStencilAttachment::onAbandon();
}

GrVkGpu* GrVkStencilAttachment::getVkGpu() const {
    SkASSERT(!this->wasDestroyed());
    return static_cast<GrVkGpu*>(this->getGpu());
}
