I am trying to use PBOs to do texture upload/update of an osg::Image in a 
thread different from the rendering thread, and render the same. I have created 
a plugin that simply updates a simple buffer (filling every channel of every 
pixel in the buffer with a value that varies over time from 0 to 1).

In the first iteration, I used an osg::Image. For increasing performance, I 
switched to using an osg::ImageStream since it uses PBO.

The relevant parts of my update plugin's code are as below:
 

Code:

/// \brief  A simple test OSG plugin that updates a buffer (by changing pixel 
values)
    class MYLIB_EXPORT TestBufferWriter : protected OpenThreads::Thread,
#ifdef USE_PBO
                                          public osg::ImageStream
#else
                                          public osg::Image  
#endif
    {
    public:
        /// \brief  constructor
        TestBufferWriter();
    ...
    protected:
        /// \brief  Buffers into which we write our updates
        unsigned char* _updateBuffers[2];
    }

    void
    TestBufferWriter::_initialize()
    {
        // Allocate two new buffers
        unsigned char* newBuffers[2];
        newBuffers[0] = new unsigned char[_width*_height*3];
        newBuffers[1] = new unsigned char[_width*_height*3];

        // Call set image using the second of the 2 new buffers created
        if(_firstTimeInit)
        {
            setImage(_width,
                     _height,
                     1,
                     GL_RGB,
                     GL_RGB,
                     GL_UNSIGNED_BYTE,
                     newBuffers[1],
                     osg::Image::NO_DELETE);
            
            _firstTimeInit = false;
        }
        else
        {
            _data = newBuffers[1];
            dirty();
        }

        //  Release any previously allocated buffers
        _releaseBuffers();
        
        // Set our member buffer pointers to the newly allocated buffers
        _updateBuffers[0] = newBuffers[0];
        _updateBuffers[1] = newBuffers[1];
        _data = _updateBuffers[1];
        dirty();
        _currentBufferIndex = 1;
    }

    void TestBufferWriter::_update()
    {
        double currentTime = osg::Timer::instance()->time_s();       
        float oscillator = (sinf(currentTime)*0.5)+0.5;
        oscillator += _randomOffset;
        int pixVal = oscillator*255.f;

        // First set the image buffer to the previously updated buffer
        setImage(_width, _height, 1, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, 
_updateBuffers[_currentBufferIndex], osg::Image::NO_DELETE);

        // Now swap buffer index so that we can update the other buffer
        _currentBufferIndex = _currentBufferIndex==0?1:0;

        // Update the other buffer by modifying pixel values
        unsigned char* imgData = _updateBuffers[_currentBufferIndex];
        memset(imgData, pixVal, _width*_height*3);
    }




I find that using PBOs, I did get a marginal speedup of frame rate(~20 FPS 
more) and a significant drop in processor usage (~20% less). However, I believe 
that the performance improvements possible must be more drastic.

Investigating further, I wrote a simple sample of my own in OpenGL where I 
update a texture exactly like I do in the osg plugin described above. While not 
using PBOs, I find the performance/framerates nearly equal to what I got with 
OpenScenegraph plugin. However, on using PBOs, I get dramatic improvements in 
performance, in the order of 10x(!) improvements in render rates. This means 
that there is a lot of scope for improving performance in my osg plugin as 
well. From the above code, can someone point out any flaws in the way I am 
using ImageStream in OpenScenegraph that is preventing me from getting the full 
benefits of using PBO?

Currently, during every update, I use osg::ImageStream setImage to map to the 
buffer on the host that I create. I am guessing there must be a memcpy being 
doing to copy from my image buffer to the PBO that image stream maintains 
internally. This seems inefficient to me. In this regard, I would like to know, 
if there is a way I can create two PBOs, and write my updates to one directly 
while using the other to render the osg::Texture with. 

Thank you!

Cheers,
Abhishek

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=57635#57635





_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to