Ejemplo n.º 1
0
bool Node::_cmdFrameDataTransmit( co::ICommand& cmd )
{
    co::ObjectICommand command( cmd );

    const co::ObjectVersion frameDataVersion =
                                             command.get< co::ObjectVersion >();
    const PixelViewport pvp = command.get< PixelViewport >();
    const Zoom zoom = command.get< Zoom >();
    const uint32_t buffers = command.get< uint32_t >();
    const uint32_t frameNumber = command.get< uint32_t >();
    const bool useAlpha = command.get< bool >();
    const uint8_t* data = reinterpret_cast< const uint8_t* >(
                command.getRemainingBuffer( command.getRemainingBufferSize( )));

    LBLOG( LOG_ASSEMBLY )
        << "received image data for " << frameDataVersion << ", buffers "
        << buffers << " pvp " << pvp << std::endl;

    LBASSERT( pvp.isValid( ));

    FrameDataPtr frameData = getFrameData( frameDataVersion );
    LBASSERT( !frameData->isReady() );

    NodeStatistics event( Statistic::NODE_FRAME_DECOMPRESS, this,
                          frameNumber );

    // Note on the const_cast: since the PixelData structure stores non-const
    // pointers, we have to go non-const at some point, even though we do not
    // modify the data.
    LBCHECK( frameData->addImage( frameDataVersion, pvp, zoom, buffers,
                                  useAlpha, const_cast< uint8_t* >( data )));
    return true;
}
Ejemplo n.º 2
0
void Pipe::_setCGDisplayID( CGDirectDisplayID id )
{
    if( _cgDisplayID == id )
        return;

    _cgDisplayID = id;
    PixelViewport pvp = getPipe()->getPixelViewport();

    if( pvp.isValid( ))
        return;

    if( id )
    {
        const CGRect displayRect = CGDisplayBounds( id );
        pvp.x = int32_t(displayRect.origin.x);
        pvp.y = int32_t(displayRect.origin.y);
        pvp.w = int32_t(displayRect.size.width);
        pvp.h = int32_t(displayRect.size.height);
    }
    else
        pvp.invalidate();

    getPipe()->setPixelViewport( pvp );
}
Ejemplo n.º 3
0
void ROIFinder::_readbackInfo( util::ObjectManager& glObjects )
{
    LBASSERT( glObjects.supportsEqTexture( ));
    LBASSERT( glObjects.supportsEqFrameBufferObject( ));

    PixelViewport pvp = _pvp;
    pvp.apply( Zoom( GRID_SIZE, GRID_SIZE ));
    pvp.w = LB_MIN( pvp.w+pvp.x, _pvpOriginal.w+_pvpOriginal.x ) - pvp.x;
    pvp.h = LB_MIN( pvp.h+pvp.y, _pvpOriginal.h+_pvpOriginal.y ) - pvp.y;

    LBASSERT( pvp.isValid());

    // copy frame buffer to texture
    const void* bufferKey = _getInfoKey( );
    util::Texture* texture =
        glObjects.obtainEqTexture( bufferKey, GL_TEXTURE_RECTANGLE_ARB );

#ifdef EQ_ROI_USE_DEPTH_TEXTURE
    texture->copyFromFrameBuffer( GL_DEPTH_COMPONENT, pvp );
#else
    texture->copyFromFrameBuffer( GL_RGBA, pvp );
#endif

    // draw zoomed quad into FBO
    const void*     fboKey = _getInfoKey( );
    util::FrameBufferObject* fbo = glObjects.getEqFrameBufferObject( fboKey );

    if( fbo )
    {
        LBCHECK( fbo->resize( _pvp.w, _pvp.h ));
    }
    else
    {
        fbo = glObjects.newEqFrameBufferObject( fboKey );
        LBCHECK( fbo->init( _pvp.w, _pvp.h, GL_RGBA32F, 0, 0 ));
    }
    fbo->bind();

    texture->bind();

    // Enable & download depth texture
    glEnable( GL_TEXTURE_RECTANGLE_ARB );

    texture->applyWrap();
    texture->applyZoomFilter( FILTER_LINEAR );

    // Enable shaders
    GLuint program = glObjects.getProgram( shaderRBInfo );
    if( program == util::ObjectManager::INVALID )
    {
        // Create fragment shader which reads depth values from
        // rectangular textures
        const GLuint shader = glObjects.newShader( shaderRBInfo,
                                                        GL_FRAGMENT_SHADER );
        LBASSERT( shader != util::ObjectManager::INVALID );

#ifdef EQ_ROI_USE_DEPTH_TEXTURE
        const GLchar* fShaderPtr = roiFragmentShader_glsl.c_str();
#else
        const GLchar* fShaderPtr = roiFragmentShaderRGB_glsl.c_str();
#endif
        EQ_GL_CALL( glShaderSource( shader, 1, &fShaderPtr, 0 ));
        EQ_GL_CALL( glCompileShader( shader ));

        GLint status;
        glGetShaderiv( shader, GL_COMPILE_STATUS, &status );
        if( !status )
            LBERROR << "Failed to compile fragment shader for ROI finder"
                    << std::endl;

        program = glObjects.newProgram( shaderRBInfo );

        EQ_GL_CALL( glAttachShader( program, shader ));
        EQ_GL_CALL( glLinkProgram( program ));

        glGetProgramiv( program, GL_LINK_STATUS, &status );
        if( !status )
        {
            LBWARN << "Failed to link shader program for ROI finder"
                   << std::endl;
            return;
        }

        // use fragment shader and setup uniforms
        EQ_GL_CALL( glUseProgram( program ));

        GLint param = glGetUniformLocation( program, "texture" );
        glUniform1i( param, 0 );
    }
    else
    {
        // use fragment shader
        EQ_GL_CALL( glUseProgram( program ));
    }

    // Draw Quad
    glDisable( GL_LIGHTING );
    glColor3f( 1.0f, 1.0f, 1.0f );

    glBegin( GL_QUADS );
        glVertex3i(      0,      0, 0 );
        glVertex3i( _pvp.w,      0, 0 );
        glVertex3i( _pvp.w, _pvp.h, 0 );
        glVertex3i(      0, _pvp.h, 0 );
    glEnd();

    // restore state
    glDisable( GL_TEXTURE_RECTANGLE_ARB );
    EQ_GL_CALL( glUseProgram( 0 ));

    fbo->unbind();

    // finish readback of info
    LBASSERT( static_cast<int32_t>(_perBlockInfo.size()) >= _pvp.w*_pvp.h*4 );

    texture = fbo->getColorTextures()[0];
    LBASSERT( texture->getFormat() == GL_RGBA );
    LBASSERT( texture->getType() == GL_FLOAT );
    texture->download( &_perBlockInfo[0] );
}
Ejemplo n.º 4
0
Images FrameData::startReadback( const Frame& frame,
                                 util::ObjectManager& glObjects,
                                 const DrawableConfig& config,
                                 const PixelViewports& regions )
{
    if( _impl->data.buffers == Frame::BUFFER_NONE )
        return Images();

    const Zoom& zoom = frame.getZoom();
    if( !zoom.isValid( ))
    {
        LBWARN << "Invalid zoom factor, skipping frame" << std::endl;
        return Images();
    }

    const eq::PixelViewport& framePVP = getPixelViewport();
    const PixelViewport      absPVP   = framePVP + frame.getOffset();
    if( !absPVP.isValid( ))
        return Images();

    Images images;

    // readback the whole screen when using textures
    if( getType() == eq::Frame::TYPE_TEXTURE )
    {
        Image* image = newImage( getType(), config );
        if( image->startReadback( getBuffers(), absPVP, zoom, glObjects ))
            images.push_back( image );
        image->setOffset( 0, 0 );
        return images;
    }
    //else read only required regions

#if 0
    // TODO: issue #85: move automatic ROI detection to eq::Channel
    PixelViewports regions;
    if( _impl->data.buffers & Frame::BUFFER_DEPTH && zoom == Zoom::NONE )
        regions = _impl->roiFinder->findRegions( _impl->data.buffers, absPVP,
                                                 zoom, frame.getAssemblyStage(),
                                                 frame.getFrameID(), glObjects);
    else
        regions.push_back( absPVP );
#endif

    LBASSERT( getType() == eq::Frame::TYPE_MEMORY );
    const eq::Pixel& pixel = getPixel();

    for( uint32_t i = 0; i < regions.size(); ++i )
    {
        PixelViewport pvp = regions[ i ] + frame.getOffset();
        pvp.intersect( absPVP );
        if( !pvp.hasArea( ))
            continue;

        Image* image = newImage( getType(), config );
        if( image->startReadback( getBuffers(), pvp, zoom, glObjects ))
            images.push_back( image );

        pvp -= frame.getOffset();
        pvp.apply( zoom );
        image->setOffset( (pvp.x - framePVP.x) * pixel.w,
                          (pvp.y - framePVP.y) * pixel.h );
    }
    return images;
}
Ejemplo n.º 5
0
void Config::activateCanvas( Canvas* canvas )
{
    LBASSERT( canvas->isStopped( ));
    LBASSERT( lunchbox::find( getCanvases(), canvas ) != getCanvases().end( ));

    const Layouts& layouts = canvas->getLayouts();
    const Segments& segments = canvas->getSegments();

    for( Layouts::const_iterator i = layouts.begin();
         i != layouts.end(); ++i )
    {
        const Layout* layout = *i;
        if( !layout )
            continue;

        const Views& views = layout->getViews();
        for( Views::const_iterator j = views.begin();
             j != views.end(); ++j )
        {
            View* view = *j;

            for( Segments::const_iterator k = segments.begin();
                 k != segments.end(); ++k )
            {
                Segment* segment = *k;
                Viewport viewport = segment->getViewport();
                viewport.intersect( view->getViewport( ));

                if( !viewport.hasArea( ))
                {
                    LBLOG( LOG_VIEW )
                        << "View " << view->getName() << view->getViewport()
                        << " doesn't intersect " << segment->getName()
                        << segment->getViewport() << std::endl;

                    continue;
                }

                Channel* segmentChannel = segment->getChannel();
                if( !segmentChannel )
                {
                    LBWARN << "Segment " << segment->getName()
                           << " has no output channel" << std::endl;
                    continue;
                }

                if ( findChannel( segment, view ))
                    continue;

                // create and add new channel
                Channel* channel = new Channel( *segmentChannel );
                channel->init(); // not in ctor, virtual method
                channel->setOutput( view, segment );

                //----- compute channel viewport:
                // segment/view intersection in canvas space...
                Viewport contribution = viewport;
                // ... in segment space...
                contribution.transform( segment->getViewport( ));

                // segment output area
                if( segmentChannel->hasFixedViewport( ))
                {
                    Viewport subViewport = segmentChannel->getViewport();
                    LBASSERT( subViewport.isValid( ));
                    if( !subViewport.isValid( ))
                        subViewport = eq::fabric::Viewport::FULL;

                    // ...our part of it
                    subViewport.apply( contribution );
                    channel->setViewport( subViewport );
                    LBLOG( LOG_VIEW )
                        << "View @" << (void*)view << ' ' << view->getViewport()
                        << " intersects " << segment->getName()
                        << segment->getViewport() << " at " << subViewport
                        << " using channel @" << (void*)channel << std::endl;
                }
                else
                {
                    PixelViewport pvp = segmentChannel->getPixelViewport();
                    LBASSERT( pvp.isValid( ));
                    pvp.apply( contribution );
                    channel->setPixelViewport( pvp );
                    LBLOG( LOG_VIEW )
                        << "View @" << (void*)view << ' ' << view->getViewport()
                        << " intersects " << segment->getName()
                        << segment->getViewport() << " at " << pvp
                        << " using channel @" << (void*)channel << std::endl;
                }

                if( channel->getWindow()->isAttached( ))
                    // parent is already registered - register channel as well
                    getServer()->registerObject( channel );
            }
        }
    }
}
Ejemplo n.º 6
0
//---------------------------------------------------------------------------
// WGL init
//---------------------------------------------------------------------------
bool Pipe::configInit()
{
    if ( !_configInitWGLEW() )
        return false;

    PixelViewport pvp = getPipe()->getPixelViewport();
    if( pvp.isValid( ))
        return true;

    // setup pvp
    // ...using gpu affinity API
    HGPUNV hGPU = 0;
    if( !_getGPUHandle( hGPU ))
        return false;

    if( hGPU != 0 )
    {
        GPU_DEVICE gpuDevice;
        gpuDevice.cb = sizeof( gpuDevice );
        const bool found = wglEnumGpuDevicesNV( hGPU, 0, &gpuDevice );
        EQASSERT( found );

        if( gpuDevice.Flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP )
        {
            const RECT& rect = gpuDevice.rcVirtualScreen;
            pvp.x = rect.left;
            pvp.y = rect.top;
            pvp.w = rect.right  - rect.left;
            pvp.h = rect.bottom - rect.top; 
        }
        else
        {
            pvp.x = 0;
            pvp.y = 0;
            pvp.w = 4096;
            pvp.h = 4096;
        }
    }
    else // ... using Win32 API
    {
        HDC dc = createWGLDisplayDC();

        pvp.x = 0;
        pvp.y = 0;
        if( dc )
        {
            pvp.w = GetDeviceCaps( dc, HORZRES );
            pvp.h = GetDeviceCaps( dc, VERTRES );
            DeleteDC( dc );
        }
        else
        {
            EQWARN << "Can't create display dc query pipe resolution: "
                   << co::base::sysError << std::endl;
            pvp.w = 2048;
            pvp.h = 2048;
        }
    }

    getPipe()->setPixelViewport( pvp );
    EQINFO << "Pipe pixel viewport " << pvp << std::endl;
    return true;
}