Anyway I'm creating a number of video textures with python-ogre v2-2WIP, updating the texture from the main thread.
I'm running into problems where the StagingTexture created via TextureGpuManager::getStagingTexture has the same width/height, i.e. when:
- minConsumptionRatioThreshold is set to 25% and fits video resolutions;
- the video resolutions are the same and minConsumptionRatioThreshold is set to 100%.
In the above cases TextureBox width/height returned from StagingTexture::mapRegion is zero for a large number of frames . This results in skipped frames/ or frames being played in the wrong video.
As a quick hack adding an offset to try to create a unique sized staging texture resolved most of the issues.
Code: Select all
Ogre::StagingTexture* stagingTexture = me.getStagingTexture( width+videoIndex*4, height+videoIndex*4, 1, 1,
textureGpu->getPixelFormat(), 100 );
This is my texture creation:
Code: Select all
if self.getHlms().getType()==ogre.HLMS_PBS:
textureType = ogre.TextureTypes.Type2DArray
else:
textureType = ogre.TextureTypes.Type2D
#'AlwaysKeepSystemRamCopy', 'Discard', 'SaveToSystemRam'
textureMgr = ogre.Root.getSingletonPtr().getRenderSystem().getTextureGpuManager()
self.videoTextureGPU = textureMgr.createTexture( self.textureName,
ogre.GpuPageOutStrategy.Discard,
ogre.TextureFlags.PrefersLoadingAsSRGB,
textureType,
ogre.ResourceGroupManager.AUTODETECT_RESOURCE_GROUP_NAME )
self.videoTextureGPU.setPixelFormat( ogre.PixelFormatGpu.PFG_RGBA8_UNORM ) #PFG_RGBA8_UINT )
self.videoTextureGPU.setTextureType( textureType )
self.videoTextureGPU.setNumMipmaps( 1 )
self.videoTextureGPU.setResolution( self.width, self.height )
Code: Select all
self.stagingTextureDataPtr = ogre.createUint8SIMD(len(self.videoBufferData))
ctypes.memmove(
ogre.castAsLongLong(self.stagingTextureDataPtr),
ogre.castAsLongLong(ogre.castAsVoidPtr(ctypes.addressof(self.videoBufferData))),
len(self.videoBufferData) )
rowAlignment = 4
dataSize = ogre.PixelFormatGpuUtils.getSizeBytes( self.width, self.height, 1, 1,
self.videoTextureGPU.getPixelFormat(), rowAlignment )
bytesPerRow = self.videoTextureGPU._getSysRamCopyBytesPerRow( 0 )
self.videoTextureGPU._transitionTo(ogre.GpuResidency.Resident, 0 )
self.videoTextureGPU._setNextResidencyStatus( ogre.GpuResidency.Resident )
stagingTexture = textureManager.getStagingTexture( self.width, self.height, 1, 1,
self.videoTextureGPU.getPixelFormat(), 100 )
#stagingTexture = textureManager.getStagingTexture( self.width+4*self.index, self.height+4*self.index, 1, 1,
# self.videoTextureGPU.getPixelFormat(), 100 )
assert(stagingTexture.uploadWillStall()==False)
stagingTexture.startMapRegion()
texBox = stagingTexture.mapRegion( self.width, self.height, 1, 1,
self.videoTextureGPU.getPixelFormat() )
## stop the assert for texture box width/height 0
if (texBox.width>0 and texBox.height>0):
texBox.copyFrom( ogre.castAsLongLong( self.stagingTextureDataPtr), self.width, self.height, bytesPerRow )
stagingTexture.stopMapRegion()
stagingTexture.upload( texBox, self.videoTextureGPU, 0, None, False )
self.videoTextureGPU.notifyDataIsReady()
else:
print (stagingTexture._getSizeBytes(),dataSize,self.textureName, self.filename)
#texBox.copyFrom( ogre.castAsLongLong( self.stagingTextureDataPtr), self.width, self.height, bytesPerRow )
stagingTexture.stopMapRegion() ## ??????
self.errorCount+=1
textureManager.removeStagingTexture( stagingTexture )
ogre.OGRE_FREE_SIMD( self.stagingTextureDataPtr, ogre.MEMCATEGORY_RESOURCE )
self.stagingTextureDataPtr = None
Code: Select all
bool TextureGpuManager_uploadTo ( Ogre::TextureGpuManager& me, Ogre::GpuResidency::GpuResidency newResidency, Ogre::TextureGpu* textureGpu, Ogre::uint32 width, Ogre::uint32 height, Ogre::uint32 videoIndex, Ogre::uint32 datalen, void* data )
{
bool err=false;
Ogre::uint8 *voidDataPtr = reinterpret_cast<Ogre::uint8*>( OGRE_MALLOC_SIMD(
sizeof(Ogre::uint8) * datalen,
Ogre::MEMCATEGORY_RESOURCE ) );
memcpy( voidDataPtr, reinterpret_cast<Ogre::uint8*>(data), datalen );
//Ogre::TextureGpuManager* textureManager = Ogre::Root::getSingletonPtr()->getRenderSystem()->getTextureGpuManager();
Ogre::uint32 rowAlignment = 4;
Ogre::uint32 dataSize = Ogre::PixelFormatGpuUtils::getSizeBytes( width, height, 1, 1,
textureGpu->getPixelFormat(), rowAlignment );
Ogre::uint32 bytesPerRow = textureGpu->_getSysRamCopyBytesPerRow( 0 );
textureGpu->_transitionTo(Ogre::GpuResidency::Resident, 0 );
textureGpu->_setNextResidencyStatus( Ogre::GpuResidency::Resident );
//Ogre::LightweightMutex mMutex;
//mMutex.lock();
Ogre::StagingTexture* stagingTexture = me.getStagingTexture( width+videoIndex*4, height+videoIndex*4, 1, 1,
textureGpu->getPixelFormat(), 100 );
stagingTexture->startMapRegion();
Ogre::TextureBox texBox = stagingTexture->mapRegion( width, height, 1, 1,
textureGpu->getPixelFormat() );
if (texBox.width>0 && texBox.height>0) {
texBox.copyFrom( voidDataPtr, width, height, bytesPerRow );
stagingTexture->stopMapRegion();
stagingTexture->upload( texBox, textureGpu, 0, 0, true );
textureGpu->notifyDataIsReady();
} else {
stagingTexture->stopMapRegion();
err = true;
}
me.removeStagingTexture( stagingTexture );
//mMutex.unlock();
OGRE_FREE_SIMD( voidDataPtr, Ogre::MEMCATEGORY_RESOURCE );
textureGpu->notifyDataIsReady();
return err;
}