// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #include "surface.hpp" #include "deviceStream.hpp" #include "cuda/error.hpp" #include "../common/allocStats.hpp" namespace VideoStitch { namespace GPU { Surface::~Surface() { delete pimpl; } CubemapSurface::~CubemapSurface() { delete pimpl; } Surface::Surface(DeviceSurface* pimpl, size_t width, size_t height) : pimpl(pimpl), _width(width), _height(height) {} CubemapSurface::CubemapSurface(DeviceCubemapSurface* pimpl, size_t length) : pimpl(pimpl), _length(length) {} DeviceSurface::~DeviceSurface() { cudaDestroyTextureObject(tex_); cudaDestroySurfaceObject(surface_); if (ownsArray_) { cudaFreeArray(array_); deviceStats.deletePtr(array_); } } DeviceSurface& Surface::get() { assert(pimpl); return *pimpl; } const DeviceSurface& Surface::get() const { assert(pimpl); return *pimpl; } DeviceCubemapSurface& CubemapSurface::get() { assert(pimpl); return *pimpl; } const DeviceCubemapSurface& CubemapSurface::get() const { assert(pimpl); return *pimpl; } bool Surface::operator==(const Surface& other) const { if (pimpl && other.pimpl) { return *pimpl == *other.pimpl; } return !pimpl && !other.pimpl; } } // namespace GPU namespace Core { Status SourceOpenGLSurface::Pimpl::acquire() { acquired = true; return CUDA_ERROR(cudaGraphicsMapResources(1, &image, stream.get())); } Status SourceOpenGLSurface::Pimpl::release() { if (acquired) { acquired = false; return CUDA_ERROR(cudaGraphicsUnmapResources(1, &image, stream.get())); } return Status::OK(); } Status PanoOpenGLSurface::Pimpl::acquire() { acquired = true; return CUDA_ERROR(cudaGraphicsMapResources(1, &image, stream.get())); } Status PanoOpenGLSurface::Pimpl::release() { if (acquired) { acquired = false; return CUDA_ERROR(cudaGraphicsUnmapResources(1, &image, stream.get())); } return Status::OK(); } Status CubemapOpenGLSurface::Pimpl::acquire() { for (int i = 0; i < 6; ++i) { FAIL_RETURN(CUDA_ERROR(cudaGraphicsMapResources(1, &resources[i], stream.get()))); } return Status::OK(); } Status CubemapOpenGLSurface::Pimpl::release() { for (int i = 0; i < 6; ++i) { FAIL_RETURN(CUDA_ERROR(cudaGraphicsUnmapResources(1, &resources[i], stream.get()))); } return Status::OK(); } Potential PanoOpenGLSurface::Pimpl::create(cudaGraphicsResource_t image, GPU::Buffer buffer, GPU::Surface* remapSurf, size_t w, size_t h) { PotentialValue stream = GPU::Stream::create(); if (stream.ok()) { return Potential(new Pimpl(image, buffer, remapSurf, w, h, stream.value())); } else { return Potential(stream.status()); } } Potential CubemapOpenGLSurface::Pimpl::create( cudaGraphicsResource_t* resources, GPU::Buffer* buffers, GPU::Buffer buffer, GPU::CubemapSurface* cubemap, GPU::Buffer tmp, size_t w, bool equiangular) { PotentialValue stream = GPU::Stream::create(); if (stream.ok()) { return Potential(new Pimpl(equiangular, resources, buffers, buffer, cubemap, tmp, w, stream.value())); } else { return Potential(stream.status()); } } PanoOpenGLSurface::Pimpl::~Pimpl() { cudaGraphicsUnregisterResource(image); } CubemapOpenGLSurface::Pimpl::~Pimpl() { for (int i = 0; i < 6; ++i) { cudaGraphicsUnregisterResource(resources[i]); } } Potential SourceOpenGLSurface::Pimpl::create(cudaGraphicsResource_t image, std::unique_ptr surf) { PotentialValue stream = GPU::Stream::create(); if (stream.ok()) { return Potential(new Pimpl(image, surf.release(), stream.value())); } else { return Potential(stream.status()); } } SourceOpenGLSurface::Pimpl::~Pimpl() { cudaGraphicsUnregisterResource(image); } } // namespace Core } // namespace VideoStitch