// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #include "fillRenderer.hpp" #include "../cuda/util.hpp" #include "cuda/error.hpp" namespace VideoStitch { namespace Render { namespace { /** * Fill rectangle kernel. */ __global__ void fillRectKernel(uint32_t* dst, uint32_t value, unsigned left, unsigned top, unsigned right, unsigned bottom, unsigned bufferWidth) { const unsigned x = left + blockIdx.x * blockDim.x + threadIdx.x; const unsigned y = top + blockIdx.y * blockDim.y + threadIdx.y; if (x < right && y < bottom) { dst[y * bufferWidth + x] = value; } } /** * Clamps a value between 0 and a maximum value. * @param value input value * @param maxValue max value */ int64_t clampZeroMax(int64_t value, int64_t maxValue) { if (value < 0) { return 0; } else if (value > maxValue) { return maxValue; } return value; } } // namespace Status FillRenderer::draw(uint32_t* dst, int64_t dstWidth, int64_t dstHeight, int64_t left, int64_t top, int64_t right, int64_t bottom, uint32_t color, uint32_t /*bgcolor*/, cudaStream_t stream) const { left = clampZeroMax(left, dstWidth); right = clampZeroMax(right, dstWidth); top = clampZeroMax(top, dstHeight); bottom = clampZeroMax(bottom, dstHeight); int64_t width = right - left; int64_t height = bottom - top; if (width <= 0 || height <= 0) { return {Origin::GPU, ErrType::ImplementationError, "Negative size for rectangle filling"}; } dim3 dimBlock(16, 16, 1); dim3 dimGrid((unsigned)Cuda::ceilDiv(width, dimBlock.x), (unsigned)Cuda::ceilDiv(height, dimBlock.y)); fillRectKernel<<<dimGrid, dimBlock, 0, stream>>>(dst, color, (unsigned)left, (unsigned)top, (unsigned)right, (unsigned)bottom, (unsigned)dstWidth); return CUDA_STATUS; } } // namespace Render } // namespace VideoStitch