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

#include "GrGLBufferImpl.h"
#include "GrGLGpu.h"

#define GL_CALL(GPU, X) GR_GL_CALL(GPU->glInterface(), X)

#ifdef SK_DEBUG
#define VALIDATE() this->validate()
#else
#define VALIDATE() do {} while(false)
#endif

GrGLBufferImpl::GrGLBufferImpl(GrGLGpu* gpu, const Desc& desc, GrGLenum bufferType)
    : fDesc(desc)
    , fBufferType(bufferType)
    , fMapPtr(nullptr) {
    if (0 == desc.fID) {
        if (gpu->caps()->mustClearUploadedBufferData()) {
            fCPUData = sk_calloc_throw(desc.fSizeInBytes);
        } else {
            fCPUData = sk_malloc_throw(desc.fSizeInBytes);
        }
        fGLSizeInBytes = 0;
    } else {
        fCPUData = nullptr;
        // We assume that the GL buffer was created at the desc's size initially.
        fGLSizeInBytes = fDesc.fSizeInBytes;
    }
    VALIDATE();
}

void GrGLBufferImpl::release(GrGLGpu* gpu) {
    VALIDATE();
    // make sure we've not been abandoned or already released
    if (fCPUData) {
        sk_free(fCPUData);
        fCPUData = nullptr;
    } else if (fDesc.fID) {
        gpu->releaseBuffer(fDesc.fID, fBufferType);
        fDesc.fID = 0;
        fGLSizeInBytes = 0;
    }
    fMapPtr = nullptr;
    VALIDATE();
}

void GrGLBufferImpl::abandon() {
    fDesc.fID = 0;
    fGLSizeInBytes = 0;
    fMapPtr = nullptr;
    sk_free(fCPUData);
    fCPUData = nullptr;
    VALIDATE();
}

void* GrGLBufferImpl::map(GrGLGpu* gpu) {
    VALIDATE();
    SkASSERT(!this->isMapped());
    if (0 == fDesc.fID) {
        fMapPtr = fCPUData;
    } else {
        fMapPtr = gpu->mapBuffer(fDesc.fID, fBufferType, fDesc.fUsage, fGLSizeInBytes,
                                 fDesc.fSizeInBytes);
        fGLSizeInBytes = fDesc.fSizeInBytes;
    }
    VALIDATE();
    return fMapPtr;
}

void GrGLBufferImpl::unmap(GrGLGpu* gpu) {
    VALIDATE();
    SkASSERT(this->isMapped());
    if (0 != fDesc.fID) {
        gpu->unmapBuffer(fDesc.fID, fBufferType, fMapPtr);
    }
    fMapPtr = nullptr;
}

bool GrGLBufferImpl::isMapped() const {
    VALIDATE();
    return SkToBool(fMapPtr);
}

bool GrGLBufferImpl::updateData(GrGLGpu* gpu, const void* src, size_t srcSizeInBytes) {
    SkASSERT(!this->isMapped());
    SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType);
    VALIDATE();
    if (srcSizeInBytes > fDesc.fSizeInBytes) {
        return false;
    }
    if (0 == fDesc.fID) {
        memcpy(fCPUData, src, srcSizeInBytes);
        return true;
    }
    gpu->bufferData(fDesc.fID, fBufferType, fDesc.fUsage, fDesc.fSizeInBytes, src,
                    srcSizeInBytes);
#if GR_GL_USE_BUFFER_DATA_NULL_HINT
    fGLSizeInBytes = fDesc.fSizeInBytes;
#else
    fGLSizeInBytes = srcSizeInBytes;
#endif
    VALIDATE();
    return true;
}

void GrGLBufferImpl::validate() const {
    SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType ||
             GR_GL_PIXEL_PACK_BUFFER == fBufferType || GR_GL_PIXEL_UNPACK_BUFFER == fBufferType ||
             GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM == fBufferType ||
             GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == fBufferType);
    // The following assert isn't valid when the buffer has been abandoned:
    // SkASSERT((0 == fDesc.fID) == (fCPUData));
    SkASSERT(nullptr == fCPUData || 0 == fGLSizeInBytes);
    SkASSERT(nullptr == fMapPtr || fCPUData || fGLSizeInBytes <= fDesc.fSizeInBytes);
    SkASSERT(nullptr == fCPUData || nullptr == fMapPtr || fCPUData == fMapPtr);
}
