[osg-users] infinite loop

Jonathan Richard jonathan.richard0 at gmail.com
Wed Oct 3 07:32:49 PDT 2007


Hi, does the osgProducer::Viewer (I use osg 1.2) is suppose to work if
the WGL_ARB_PIXEL_FORNAT is not supported? It seems fall in an
infinite loop ( in the method VisualChooser::choose( Display *dpy, int
screen, bool strict_adherence)  ) when this extension is not
supported. The variable "failed" is always true (can not be change to
false) so the while(failed) is always executed The code is:

VisualInfo *VisualChooser::choose( Display *dpy, int screen, bool
strict_adherence)
{
    if (_vinfo)
        return _vinfo;

    if (_visual_attributes.empty())
        setSimpleConfiguration();

    int vid;
    bool failed = false;

    WGLExtensions *ext = WGLExtensions::instance();
    if (ext && ext->isSupported(WGLExtensions::ARB_pixel_format))
    {
        do
        {
            std::vector<int> attribs;
            for (std::vector<VisualAttribute>::const_iterator
i=_visual_attributes.begin(); i!=_visual_attributes.end(); ++i)
                applyAttribute(*i, attribs);
            attribs.push_back(0);

            unsigned int num_formats;
            failed = !ext->wglChoosePixelFormat(*dpy,
&attribs.front(), 0, 1, &vid, &num_formats) || num_formats == 0;
            if (failed)
            {
                // **** DRIVER BUG? It seems that some ATI cards don't support
                // **** the WGL_SWAP_METHOD_ARB attribute. Now we try to remove
                // **** it from the attribute list and choose a pixel
format again.
                for (std::vector<int>::iterator k=attribs.begin();
k!=attribs.end(); ++k)
                {
                    if (*k == WGL_SWAP_METHOD_ARB)
                    {
                        // attribute come in sequential attribute,paramter pairs
                        // as WGL specifications so we need to delete
two entries
                        attribs.erase(k,k+2);
                        break;
                    }
                }

                failed = !ext->wglChoosePixelFormat(*dpy,
&attribs.front(), 0, 1, &vid, &num_formats) || num_formats == 0;
            }

            if (failed)
            {
                if (strict_adherence || _visual_attributes.empty())
                    break;

                std::cerr << "Producer::VisualChooser: the requested
visual is not available, trying to relax attributes..." << std::endl;
                _visual_attributes.pop_back();
            }

        } while (failed);
    }

    if (failed || !ext || !ext->isSupported(WGLExtensions::ARB_pixel_format))
    {
        std::cerr << "Producer::VisualChooser: unable to setup a valid
visual with WGL extensions, switching to compatibility mode" <<
std::endl;

        failed = false;
        do
        {
            PIXELFORMATDESCRIPTOR pfd;
            ZeroMemory(&pfd, sizeof(pfd));
            pfd.nSize = sizeof(pfd);
            pfd.nVersion = 1;
            pfd.dwFlags = PFD_DRAW_TO_WINDOW;
            pfd.iLayerType = PFD_MAIN_PLANE;

            for (std::vector<VisualAttribute>::const_iterator
i=_visual_attributes.begin(); i!=_visual_attributes.end(); ++i)
            {
                if (i->attribute() == UseGL)             pfd.dwFlags
|= PFD_SUPPORT_OPENGL;
                if (i->attribute() == DoubleBuffer)      pfd.dwFlags
|= PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE;
                if (i->attribute() == Stereo)            pfd.dwFlags
|= PFD_STEREO;
                if (i->attribute() == RGBA)
pfd.iPixelType = PFD_TYPE_RGBA;
                if (i->attribute() == BufferSize)
pfd.cColorBits = i->parameter();
                if (i->attribute() == RedSize)           pfd.cRedBits
= i->parameter();
                if (i->attribute() == GreenSize)
pfd.cGreenBits = i->parameter();
                if (i->attribute() == BlueSize)          pfd.cBlueBits
= i->parameter();
                if (i->attribute() == AlphaSize)
pfd.cAlphaBits = i->parameter();
                if (i->attribute() == AccumRedSize)
pfd.cAccumRedBits = i->parameter();
                if (i->attribute() == AccumGreenSize)
pfd.cAccumGreenBits = i->parameter();
                if (i->attribute() == AccumBlueSize)
pfd.cAccumBlueBits = i->parameter();
                if (i->attribute() == AccumAlphaSize)
pfd.cAccumAlphaBits = i->parameter();
                if (i->attribute() == DepthSize)
pfd.cDepthBits = i->parameter();
                if (i->attribute() == StencilSize)
pfd.cStencilBits = i->parameter();
                if (i->attribute() == AuxBuffers)
pfd.cAuxBuffers = i->parameter();
            }

            pfd.cAccumBits = pfd.cAccumRedBits + pfd.cAccumGreenBits +
pfd.cAccumBlueBits + pfd.cAccumAlphaBits;

            vid = ChoosePixelFormat(*dpy, &pfd);
            if ( vid != 0 )
            {
              // Is this additional check neccessary ?
              // Did anyone encountered a situation where
              // ChoosePixelFormat returned PXIELFORMAT worse than required ?
              _visual_id = static_cast<unsigned int>(vid);
              VisualInfo pfd;
              DescribePixelFormat(*dpy, _visual_id,
sizeof(PIXELFORMATDESCRIPTOR), &pfd);
              bool boolOK = true;
              for (std::vector<VisualAttribute>::const_iterator
i=_visual_attributes.begin(); i!=_visual_attributes.end(); ++i)
              {
                  if (i->attribute() == UseGL)             boolOK &=
!!( pfd.dwFlags & PFD_SUPPORT_OPENGL );
                  if (i->attribute() == DoubleBuffer)      boolOK &=
!!( pfd.dwFlags & ( PFD_DOUBLEBUFFER | PFD_SWAP_EXCHANGE ) );
                  if (i->attribute() == Stereo)            boolOK &=
!!( pfd.dwFlags & PFD_STEREO );
                  if (i->attribute() == RGBA)              boolOK &=
pfd.iPixelType == PFD_TYPE_RGBA;
                  if (i->attribute() == BufferSize)        boolOK &=
pfd.cColorBits >= i->parameter();
                  if (i->attribute() == RedSize)           boolOK &=
pfd.cRedBits >= i->parameter();
                  if (i->attribute() == GreenSize)         boolOK &=
pfd.cGreenBits >= i->parameter();
                  if (i->attribute() == BlueSize)          boolOK &=
pfd.cBlueBits >= i->parameter();
                  if (i->attribute() == AlphaSize)         boolOK &=
pfd.cAlphaBits >= i->parameter();
                  if (i->attribute() == AccumRedSize)      boolOK &=
pfd.cAccumRedBits >= i->parameter();
                  if (i->attribute() == AccumGreenSize)    boolOK &=
pfd.cAccumGreenBits >= i->parameter();
                  if (i->attribute() == AccumBlueSize)     boolOK &=
pfd.cAccumBlueBits >= i->parameter();
                  if (i->attribute() == AccumAlphaSize)    boolOK &=
pfd.cAccumAlphaBits >= i->parameter();
                  if (i->attribute() == DepthSize)         boolOK &=
pfd.cDepthBits >= i->parameter();
                  if (i->attribute() == StencilSize)       boolOK &=
pfd.cStencilBits >= i->parameter();
                  if (i->attribute() == AuxBuffers)        boolOK &=
pfd.cAuxBuffers >= i->parameter();
              }
              if ( !boolOK )
                vid = 0;
            }

            if( vid == 0 )
            {
                failed = true;
                if (strict_adherence || _visual_attributes.empty())
                    break;

                std::cerr << "Producer::VisualChooser: the requested
visual is not available, trying to relax attributes..." << std::endl;
                _visual_attributes.pop_back();
            }

        } while (failed);

    }

    if (failed)
    {
        std::cerr << "Producer::VisualChooser: could not choose the
pixel format" << std::endl;
        return 0;
    }

    _visual_id = static_cast<unsigned int>(vid);

    // we set _vinfo for compatibility, but it's going to be unused
    // because the pixel format is usually chosen by visual ID rather
    // than by descriptor.
    _vinfo = new VisualInfo;
    DescribePixelFormat(*dpy, _visual_id,
sizeof(PIXELFORMATDESCRIPTOR), _vinfo);

    return _vinfo;
}



More information about the osg-users mailing list