コード例 #1
0
void main_thread(
	AppData& app_data,
	CommonData& common,
	const std::string& screen_name
)
{
#ifdef CLOUD_TRACE_USE_NV_copy_image
	x11::Display display(screen_name.empty()?nullptr:screen_name.c_str());
#else
	const x11::Display& display = common.display;
	(void)screen_name;
#endif

	static int visual_attribs[] =
	{
		GLX_DRAWABLE_TYPE   , GLX_PIXMAP_BIT,
		GLX_RENDER_TYPE     , GLX_RGBA_BIT,
		GLX_X_VISUAL_TYPE   , GLX_TRUE_COLOR,
		GLX_RED_SIZE        , 8,
		GLX_GREEN_SIZE      , 8,
		GLX_BLUE_SIZE       , 8,
		GLX_ALPHA_SIZE      , 8,
		None
	};

	glx::FBConfig fbc = glx::FBConfigs(
		display,
		visual_attribs
	).FindBest(display);

	x11::VisualInfo vi(display, fbc);

	x11::Pixmap xpm(display, vi, 8, 8);
	glx::Pixmap gpm(display, vi, xpm);

#ifdef CLOUD_TRACE_USE_NV_copy_image
	glx::Context context(display, fbc, 3, 3);
#else
	glx::Context context(display, fbc, common.context, 3, 3);
#endif

	context.MakeCurrent(gpm);

	common.thread_ready.Signal();

	common.master_ready.Wait();

	if(!common.Done())
	{
		try { thread_loop(app_data, common, display, context); }
		catch(...)
		{
			common.PushError(std::current_exception());
		}
	}

	context.Release(display);
}
コード例 #2
0
ファイル: glx_main.cpp プロジェクト: detunized/oglplus
void example_thread_main(ExampleThreadData& data)
{
	const ExampleThreadData::Common& common = data.common();
	const x11::ScreenNames& sn = common.screen_names;
	// pick one of the available display screens
	// for this thread
	std::size_t disp_idx = data.thread_index;
	if(sn.size() > 1) ++disp_idx;
	disp_idx %= sn.size();
	// open the picked display
	x11::Display display(sn[disp_idx].c_str());
	// initialize the pixelmaps and the sharing context
	x11::Pixmap xpm(display, common.vi, 8, 8);
	glx::Pixmap gpm(display, common.vi, xpm);
	glx::Context ctx(display, common.fbc, common.ctx, 3, 3);

	ctx.MakeCurrent(gpm);

	// signal that the context is created
	common.thread_ready.Signal();

	// wait for the example to be created
	// in the main thread
	common.master_ready.Wait();
	// if something failed - quit
	if(common.failure)
	{
		common.thread_ready.Signal();
		return;
	}
	else
	{
		try
		{
			assert(common.example);
			// call makeExampleThread
			std::unique_ptr<ExampleThread> example_thread(
				makeExampleThread(
					*common.example,
					data.thread_index,
					common.example_params
				)
			);
			data.example_thread = example_thread.get();
			// signal that it is created
			common.thread_ready.Signal();
			// wait for the main thread
			common.master_ready.Wait();
			// if something failed - quit
			if(common.failure) return;

			// start rendering
			while(!common.done && !common.failure)
			{
				example_thread->Render(common.clock);
				glFlush();
			}
			data.example_thread = nullptr;
		}
		catch(...)
		{
			data.example_thread = nullptr;
			throw;
		}
	}
	ctx.Release(display);
}
コード例 #3
0
ファイル: blockupdater.cpp プロジェクト: aveminus/freq
void BlockUpdater::
    processUpdates(bool isMainThread)
{
    if (!isMainThread) {
        /**
          * MergerTexture needs to prepare the block when it is about to be rendered.
          * Which is a tad late and requires a new FBO and then a swap back to the main FBO.
          *
          * Then after a glFlush the update thread can write to the block, but not before
          * the glFlush as the merged texture might not be ready. updater_->processUpdates
          * should check this and put the update on hold until showNewTexture has been called,
          * indicating that a new frame has begun an thus that there has been a glFlush since
          * MergerTexture.
          */

        EXCEPTION_ASSERTX(false, "Painting on blocks from the update thread is not implemented");
    }

    list<pair<pBlock, DrawFunc>> q;
    queue_->swap(q);

    if (q.empty ())
        return;

    GlGroupMarker gpm("ProcessUpdates");

    if (!fbo2block_)
        fbo2block_.reset (new Fbo2Block);

    // draw multiple updates to a block together
    map<pBlock, list<DrawFunc>> p;
    for (auto i = q.begin (); i != q.end (); i++)
        p[i->first].push_back(move(i->second));

    // release resources bound in function objects
    q_success_.clear ();

    list<pair<pBlock, DrawFunc>> q_failed;
    map<Heightmap::pBlock,GlTexture::ptr> textures;
    for (auto i = p.begin (); i != p.end (); i++)
    {
        const pBlock& block = i->first;

        glProjection M;
        if (isMainThread)
            textures[block] = block->sourceTexture ();
        else
            textures[block] = Heightmap::Render::BlockTextures::get1 ();

        auto fbo_mapping = fbo2block_->begin (block->getOverlappingRegion (), block->sourceTexture (), textures[block], M);

        for (auto j = i->second.begin (); j != i->second.end (); j++)
        {
            DrawFunc& draw = *j;

            // try again next frame with draw calls that return false (i.e if a sync object isn'r ready yet)
            // keep successfull draw calls around to prevent opengl resources from being reused (causing sync or corrupted data) before opengl is done with them
            (draw(M) ? q_success_ : q_failed)
               .push_back (pair<pBlock, DrawFunc>(block,move(*j)));
        }

        fbo_mapping.release ();
    }

    for (const auto& v : textures)
        v.first->setTexture(v.second);

    // reinsert failed draw attempts
    auto w = queue_.write ();
    w->swap (q_failed);

    // if any new updates arrived during processing push any failed draw attempts to the back of the queue
    for (auto& a : q_failed)
        w->push_back (std::move(a));
}
コード例 #4
0
bool QueueThread::doStartup()
{
   coreprintln("Initializing startup");
   
   // In startup
   // Send a msg for a parameter and wait for reply then Nav2 is 
   // considered started
   // Test to wait for msg before sending
   {
      WFAPISync sync(&m_guiMonitor);
      isab::Buffer buf;
      bool readRes = false;
      do {
         readRes = m_guiChannel->readData(&buf, &m_guiMonitor);
      } while (!readRes && !m_shutDown);
               
      if (buf.getLength() > 8) {
         buf.setReadPos(4); // Start after version and length
         std::auto_ptr<isab::GuiProtMess> guiProtMess(
            isab::GuiProtMess::createMsgFromBuf(&buf));
         nav2log << "QueueThread run got first msg from Nav2, id " 
                 << guiProtMess->getMessageID() << endl;
      } else {
         nav2log << "QueueThread run got first msg from Nav2, empty"
                 << endl;
      }
   }
   for (size_t i = 0; i < m_initialMsgs.size(); ++i) {
      m_nav2API->sendGuiMessage(m_initialMsgs[i]);
      m_initialMsgs[i]->deleteMembers();
      delete m_initialMsgs[i];
      m_initialMsgs[i] = NULL;
   }
   // Timeout. If there is a problem this might happen.
   // Send parameter get for wayfinder username.
   isab::GeneralParameterMess gpm(
      (uint16)isab::GuiProtEnums::paramUserAndPassword);
   wf_uint16 reqID = m_nav2API->sendGuiMessage(&gpm);
   // Wait for reply, then Nav2 is up and running!
   StatusCode startupCode = OK;
   while (m_inStartup && !m_shutDown) {
      WFAPISync sync(&m_guiMonitor);
      isab::Buffer buf;
      m_guiChannel->readData(&buf, &m_guiMonitor);
      if (buf.getLength() != 0) {
         // Check if it is the reply we want!
         while (buf.remaining() > 4) {
            // Start after version and length
            buf.setReadPos(buf.getReadPos() + 4); 
            std::auto_ptr<isab::GuiProtMess> guiProtMess(
               isab::GuiProtMess::createMsgFromBuf(&buf));
            if (guiProtMess.get() != NULL && 
                guiProtMess->getMessageID() == reqID) {
               m_inStartup = false;
               // Set startup result
               startupCode = OK;
            } else if (guiProtMess.get() != NULL && 
                       guiProtMess->getMessageType() == 
                       isab::GuiProtEnums::SET_GENERAL_PARAMETER) {
               // Check if to store it for later use in MapLib below
               isab::GeneralParameterMess* mess = 
                  static_cast<isab::GeneralParameterMess*> (
                     guiProtMess.get());
               m_nav2API->handleSetParameter(*mess);
               if (mess->getParamId() == 
                   isab::GuiProtEnums::paramMapCacheSize ||
                   mess->getParamId() == 
                   isab::GuiProtEnums::paramPoiCategories ||
                   mess->getParamId() == 
                   isab::GuiProtEnums::userTrafficUpdatePeriod ||
                   mess->getParamId() ==
                   isab::GuiProtEnums::paramDistanceMode)
               {
                  m_mapLibParams.push_back(mess);
                  guiProtMess.release();
               }
            } else if (guiProtMess.get() != NULL && 
                       guiProtMess->getMessageType() == 
                       isab::GuiProtEnums::SOUND_FILE_LIST) {
               nav2log << "QueueThread run got SOUND_FILE_LIST!"
                       << endl;
               // Send it to NavigationInterfaceImpl
               m_nav2API->getNavigationInterface().getImpl()->
                  receiveAsynchronousReply(
                     *guiProtMess, RequestID( 
                        RequestID::INVALID_REQUEST_ID));
            }
            if (guiProtMess.get() != NULL) {
               guiProtMess->deleteMembers();
            }
         }
      } else {
         // Wait for data
         m_guiMonitor.wait();
      }
   }

   coreprintln("Startup is now complete.");
   
   // Call startupComplete
   m_nav2API->startupComplete(startupCode);

   return true;
}