Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:02

0001 #include <iostream>
0002 #include <iomanip>
0003 #include <csignal>
0004 
0005 #include <cuda_runtime.h>
0006 #include "QU.hh"
0007 
0008 #include "SFrameConfig.hh"
0009 #include "SComp.h"
0010 #include "SStr.hh"
0011 #include "SPath.hh"
0012 #include "SLOG.hh"
0013 #include "NP.hh"
0014 #include "Frame.h"
0015 
0016 #define SIMG_IMPLEMENTATION 1 
0017 #include "SIMG.h"
0018 
0019 
0020 const plog::Severity Frame::LEVEL = SLOG::EnvLevel("Frame", "DEBUG" ); 
0021 
0022 unsigned Frame::getNumPixels() const 
0023 {
0024     return num_pixels ; 
0025 }
0026 
0027 /**
0028 Frame::Frame
0029 --------------
0030 
0031 Instanciated by:
0032 
0033 1. CSGOptiX::CSGOptiX with null device pointer args
0034 2. Six::Six with device pointers fed in 
0035 
0036 Accepting device buffer pointer arguments was done to allow this 
0037 class to be used with OptiX 6 workflow optix::Buffer
0038 
0039 HMM: could use QEvt to hold the pixel, isect, photon ?
0040 **/
0041 
0042 
0043 template<typename T> 
0044 T* Frame::DeviceAlloc(unsigned num_pixels, bool enabled)
0045 {
0046     return enabled ? QU::device_alloc<T>(num_pixels,"Frame::DeviceAllo:num_pixels") : nullptr ; 
0047 }
0048 
0049 template uchar4* Frame::DeviceAlloc<uchar4>(unsigned num_pixels, bool enabled); 
0050 template float4* Frame::DeviceAlloc<float4>(unsigned num_pixels, bool enabled); 
0051 template quad4*  Frame::DeviceAlloc<quad4>( unsigned num_pixels, bool enabled); 
0052 
0053 
0054 Frame::Frame(int width_, int height_, int depth_, uchar4* d_pixel_, float4* d_isect_, quad4* d_fphoton_ )
0055     :
0056     mask(SFrameConfig::FrameMask()),
0057     width(width_),
0058     height(height_),
0059     depth(depth_),
0060     channels(4),
0061     jpg_quality(SStr::GetEValue<int>("QUALITY", 50)),
0062     img(new SIMG(width, height, channels,  nullptr )),
0063     num_pixels(width*height),  
0064     d_pixel(d_pixel_ == nullptr     ? DeviceAlloc<uchar4>(num_pixels, mask & SCOMP_PIXEL   ) : d_pixel_  ),
0065     d_isect(d_isect_ == nullptr     ? DeviceAlloc<float4>(num_pixels, mask & SCOMP_ISECT   ) : d_isect_  ),
0066 #ifdef WITH_FRAME_PHOTON
0067     d_fphoton(d_fphoton_ == nullptr ? DeviceAlloc<quad4>( num_pixels, mask & SCOMP_FPHOTON ) : d_fphoton_)
0068 #else
0069     d_dummy(nullptr)  
0070 #endif
0071 {
0072     assert( depth == 1 && num_pixels > 0 ); 
0073 }
0074 
0075 
0076 /**
0077 Frame::setExternalDevicePixels
0078 -------------------------------
0079 
0080 Does nothing when there is no change in the pointer 
0081 
0082 **/
0083 
0084 void Frame::setExternalDevicePixels(uchar4* _d_pixel )
0085 {
0086     if( _d_pixel == d_pixel ) return ; 
0087 
0088     if( d_pixel ) QU::device_free<uchar4>(d_pixel ); 
0089     d_pixel = _d_pixel ; 
0090 }
0091 
0092 
0093 
0094 /**
0095 Frame::download from GPU buffers into vectors
0096 -----------------------------------------------
0097 
0098 This is invoked from CSGOptiX::snap
0099 The vectors are resized to num_pixels before the copy. 
0100 
0101 **/
0102 void Frame::download_(bool flip_vertical)
0103 {
0104     if(d_pixel)   QU::Download<uchar4>(pixel, d_pixel, num_pixels ); 
0105     if(d_isect)   QU::Download<float4>(isect, d_isect, num_pixels ); 
0106 #ifdef WITH_FRAME_PHOTON
0107     if(d_fphoton) QU::Download<quad4>(photon, d_fphoton, num_pixels ); 
0108 #endif
0109 
0110     if(d_pixel) 
0111     {
0112         img->setData( getPixelData(), flip_vertical ); 
0113     }
0114 }
0115 
0116 void Frame::download()
0117 {
0118     download_(true); 
0119 }
0120 void Frame::download_inverted()
0121 {
0122     download_(false); 
0123 }
0124 
0125 
0126 
0127 unsigned char* Frame::getPixelData() const {     return d_pixel ? (unsigned char*)pixel.data() : nullptr ; }
0128 float*         Frame::getIntersectData() const { return d_isect ? (float*)isect.data()         : nullptr ; }
0129 #ifdef WITH_FRAME_PHOTON
0130 float*         Frame::getFPhotonData() const {   return d_fphoton ? (float*)fphoton.data()     : nullptr ; }
0131 #endif
0132 
0133 void Frame::annotate( const char* bottom_line, const char* top_line, int line_height )
0134 {
0135     img->annotate( bottom_line, top_line, line_height ); 
0136 }
0137 
0138 void Frame::write(const char* outdir_, int quality) const 
0139 {
0140     const char* outdir = SPath::Resolve(outdir_, DIRPATH); 
0141     writePNG(outdir, "f_pixels.png");  
0142     writeJPG(outdir, "f_pixels.jpg", quality);  
0143     writeIsect(outdir, "f_isect.npy" ); // formerly posi.npy
0144 #ifdef WITH_FRAME_PHOTON
0145     writeFPhoton(outdir, "f_photon.npy" ); 
0146 #endif
0147 }
0148 
0149 void Frame::writePNG(const char* dir, const char* name) const 
0150 {
0151     img->writePNG(dir, name); 
0152 }
0153 void Frame::writePNG(const char* path) const 
0154 {
0155     img->writePNG(path); 
0156 }
0157 
0158 void Frame::writeJPG(const char* dir, const char* name, int quality) const 
0159 {
0160     img->writeJPG(dir, name, quality > 0 ? quality : jpg_quality ); 
0161 }
0162 void Frame::writeJPG(const char* path, int quality) const 
0163 {
0164     img->writeJPG(path, quality > 0 ? quality : jpg_quality ); 
0165 }
0166 
0167 
0168 void Frame::writeIsect( const char* dir, const char* name) const 
0169 {
0170     float* isd = getIntersectData() ;
0171     if(isd) NP::Write(dir, name, isd, height, width, 4 );
0172 }
0173 
0174 #ifdef WITH_FRAME_PHOTON
0175 void Frame::writeFPhoton( const char* dir, const char* name) const 
0176 {
0177     float* fpd = getFPhotonData() ;  
0178     if(fpd) NP::Write(dir, name, fpd, height, width, 4, 4 );
0179 }
0180 #endif
0181 
0182 void Frame::snap( const char* path )
0183 {
0184     LOG(LEVEL) << "[" ; 
0185 
0186     LOG(LEVEL) << "[ writeJPG " ; 
0187     writeJPG( path ); 
0188     LOG(LEVEL) << "] writeJPG " ; 
0189 
0190 
0191     LOG(LEVEL) << "[ writeIntersectData " ; 
0192     const char* fold = SPath::Dirname(path); 
0193     float* isd = getIntersectData() ;
0194     if(isd) NP::Write(fold, "isect.npy", isd, height, width, 4 );
0195     LOG(LEVEL) << "] writeIntersectData " ; 
0196 
0197 
0198 #ifdef WITH_FRAME_PHOTON
0199     LOG(LEVEL) << "[ writeFPhoton " ; 
0200     float* fpd = getFPhotonData() ;  
0201     if(fpd) NP::Write(fold, "fphoton.npy", fpd, height, width, 4, 4 );
0202     LOG(LEVEL) << "] writeFPhoton " ; 
0203 #endif
0204 
0205     LOG(LEVEL) << "]" ; 
0206 }
0207 
0208