// // Resource.cpp // interface/src/gpu // // Created by Sam Gateau on 10/8/2014. // Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "Context.h" #include "Resource.h" #include using namespace gpu; Resource::Size Resource::Sysmem::allocateMemory(Byte** dataAllocated, Size size) { if ( !dataAllocated ) { qWarning() << "Buffer::Sysmem::allocateMemory() : Must have a valid dataAllocated pointer."; return NOT_ALLOCATED; } // Try to allocate if needed Size newSize = 0; if (size > 0) { // Try allocating as much as the required size + one block of memory newSize = size; (*dataAllocated) = new Byte[newSize]; // Failed? if (!(*dataAllocated)) { qWarning() << "Buffer::Sysmem::allocate() : Can't allocate a system memory buffer of " << newSize << "bytes. Fails to create the buffer Sysmem."; return NOT_ALLOCATED; } } // Return what's actually allocated return newSize; } void Resource::Sysmem::deallocateMemory(Byte* dataAllocated, Size size) { if (dataAllocated) { delete[] dataAllocated; } } Resource::Sysmem::Sysmem() : _stamp(0), _size(0), _data(NULL) { } Resource::Sysmem::Sysmem(Size size, const Byte* bytes) : _stamp(0), _size(0), _data(NULL) { if (size > 0) { _size = allocateMemory(&_data, size); if (_size >= size) { if (bytes) { memcpy(_data, bytes, size); } } } } Resource::Sysmem::~Sysmem() { deallocateMemory( _data, _size ); _data = NULL; _size = 0; } Resource::Size Resource::Sysmem::allocate(Size size) { if (size != _size) { Byte* newData = 0; Size newSize = 0; if (size > 0) { Size allocated = allocateMemory(&newData, size); if (allocated == NOT_ALLOCATED) { // early exit because allocation failed return 0; } newSize = allocated; } // Allocation was successful, can delete previous data deallocateMemory(_data, _size); _data = newData; _size = newSize; _stamp++; } return _size; } Resource::Size Resource::Sysmem::resize(Size size) { if (size != _size) { Byte* newData = 0; Size newSize = 0; if (size > 0) { Size allocated = allocateMemory(&newData, size); if (allocated == NOT_ALLOCATED) { // early exit because allocation failed return _size; } newSize = allocated; // Restore back data from old buffer in the new one if (_data) { Size copySize = ((newSize < _size)? newSize: _size); memcpy( newData, _data, copySize); } } // Reallocation was successful, can delete previous data deallocateMemory(_data, _size); _data = newData; _size = newSize; _stamp++; } return _size; } Resource::Size Resource::Sysmem::setData( Size size, const Byte* bytes ) { if (allocate(size) == size) { if (size && bytes) { memcpy( _data, bytes, _size ); _stamp++; } } return _size; } Resource::Size Resource::Sysmem::setSubData( Size offset, Size size, const Byte* bytes) { if (size && ((offset + size) <= getSize()) && bytes) { memcpy( _data + offset, bytes, size ); _stamp++; return size; } return 0; } Resource::Size Resource::Sysmem::append(Size size, const Byte* bytes) { if (size > 0) { Size oldSize = getSize(); Size totalSize = oldSize + size; if (resize(totalSize) == totalSize) { return setSubData(oldSize, size, bytes); } } return 0; } Buffer::Buffer() : Resource(), _sysmem(NULL), _gpuObject(NULL) { _sysmem = new Sysmem(); } Buffer::~Buffer() { if (_sysmem) { delete _sysmem; _sysmem = 0; } if (_gpuObject) { delete _gpuObject; _gpuObject = 0; } } Buffer::Size Buffer::resize(Size size) { return editSysmem().resize(size); } Buffer::Size Buffer::setData(Size size, const Byte* data) { return editSysmem().setData(size, data); } Buffer::Size Buffer::setSubData(Size offset, Size size, const Byte* data) { return editSysmem().setSubData( offset, size, data); } Buffer::Size Buffer::append(Size size, const Byte* data) { return editSysmem().append( size, data); }