Ejemplo n.º 1
0
void MapWindow::Initialize() {
#ifndef ENABLE_OPENGL
    ScopeLock Lock(Surface_Mutex);
#endif
    // Reset common topology and waypoint label declutter, first init. Done also in other places.
    ResetLabelDeclutter();

    // Default draw area is full screen, no opacity
    MapRect = MainWindow.GetClientRect();
    DrawRect = MapRect;
    UpdateActiveScreenZone(MapRect);

    UpdateTimeStats(true);

#ifndef ENABLE_OPENGL
    // paint draw window black to start
    DrawSurface.SetBackgroundTransparent();
	DrawSurface.Blackness(MapRect.left, MapRect.top,MapRect.right-MapRect.left, MapRect.bottom-MapRect.top);

    hdcMask.SetBackgroundOpaque();
    BackBufferSurface.Blackness(MapRect.left, MapRect.top,MapRect.right-MapRect.left, MapRect.bottom-MapRect.top);
#endif

    // This is just here to give fully rendered start screen
    UpdateInfo(&GPS_INFO, &CALCULATED_INFO);
    MapDirty = true;

    FillScaleListForEngineeringUnits();
    zoom.RequestedScale(zoom.Scale());
    zoom.ModifyMapScale();

    LKUnloadFixedBitmaps();
    LKUnloadProfileBitmaps();

	LKLoadFixedBitmaps();
	LKLoadProfileBitmaps();

	// This will reset the function for the new ScreenScale
	PolygonRotateShift((POINT*)NULL,0,0,0,DisplayAngle+1);

	// Restart from moving map
	if (MapSpaceMode!=MSM_WELCOME) SetModeType(LKMODE_MAP, MP_MOVING);

	// These should be better checked. first_run is forcing also cache update for topo.
	ForceRenderMap=true;
	first_run=true;
    // Signal that draw thread can run now
    Initialised = TRUE;
#ifndef ENABLE_OPENGL
    drawTriggerEvent.set();
#endif
}
Ejemplo n.º 2
0
void MapWindow::DrawThread ()
{
  while ((!ProgramStarted) || (!Initialised)) {
	Poco::Thread::sleep(50);
  }

  #if TRACETHREAD
  StartupStore(_T("##############  DRAW threadid=%d\n"),GetCurrentThreadId());
  #endif

  #if TESTBENCH
  StartupStore(_T("... DrawThread START%s"),NEWLINE);
  #endif

  // THREADRUNNING = FALSE;
  THREADEXIT = FALSE;

  bool lastdrawwasbitblitted=false;

  //
  // Big LOOP
  //

  while (!CLOSETHREAD)
  {
	if(drawTriggerEvent.tryWait(5000))
	if (CLOSETHREAD) break; // drop out without drawing

	if ((!THREADRUNNING) || (!GlobalRunning)) {
        Poco::Thread::sleep(50);
		continue;
	}
    drawTriggerEvent.reset();

#ifdef HAVE_CPU_FREQUENCY
    const ScopeLockCPU cpu;
#endif

    ScopeLock Lock(Surface_Mutex);

	// Until MapDirty is set true again, we shall only repaint the screen. No Render, no calculations, no updates.
	// This is intended for very fast immediate screen refresh.
	//
	// MapDirty is set true by:
	//   - TriggerRedraws()  in calculations thread
	//   - RefreshMap()      in drawthread generally
	//


	extern POINT startScreen, targetScreen;
	extern bool OnFastPanning;
	// While we are moving in bitblt mode, ignore RefreshMap requests from LK
	// unless a timeout was triggered by MapWndProc itself.
	if (OnFastPanning) {
		MapDirty=false;
	}

	// We must check if we are on FastPanning, because we may be in pan mode even while
	// the menu buttons are active and we are using them, accessing other functions.
	// In that case, without checking OnFastPanning, we would fall back here and repaint
	// with bitblt everytime, while instead we were asked a simple fastrefresh!
	//
	// Notice: we could be !MapDirty without OnFastPanning, of course!
	//
	if (!MapDirty && !ForceRenderMap && OnFastPanning && !first_run) {

		if (!mode.Is(Mode::MODE_TARGET_PAN) && mode.Is(Mode::MODE_PAN)) {

			const int fromX=startScreen.x-targetScreen.x;
			const int fromY=startScreen.y-targetScreen.y;

            PixelRect  clipSourceArea(MapRect); // Source Rectangle
            RasterPoint clipDestPoint(clipSourceArea.GetOrigin()); // destination origin position
            PixelRect  WhiteRectV(MapRect); // vertical White band (left or right)
            PixelRect  WhiteRectH(MapRect); // horizontal White band (top or bottom)

            if (fromX<0) {
                clipSourceArea.right += fromX; // negative fromX
                clipDestPoint.x -= fromX;
                WhiteRectV.right = WhiteRectV.left - fromX;
                WhiteRectH.left = WhiteRectV.right;
            } else {
                clipSourceArea.left += fromX;
                WhiteRectV.left = WhiteRectV.right - fromX;
                WhiteRectH.right = WhiteRectV.left;
            }

            if (fromY<0) {
                clipSourceArea.bottom += fromY; // negative fromX
                clipDestPoint.y -= fromY;
                WhiteRectH.bottom = WhiteRectH.top - fromY;
            } else {
                clipSourceArea.top += fromY;
                WhiteRectH.top = WhiteRectH.bottom - fromY;
            }

#ifndef USE_GDI
            ScopeLock Lock(BackBuffer_Mutex);
#endif

            BackBufferSurface.Whiteness(WhiteRectV.left, WhiteRectV.top, WhiteRectV.GetSize().cx, WhiteRectV.GetSize().cy);
            BackBufferSurface.Whiteness(WhiteRectH.left, WhiteRectH.top, WhiteRectH.GetSize().cx, WhiteRectH.GetSize().cy);
            BackBufferSurface.Copy(clipDestPoint.x,clipDestPoint.y,
                clipSourceArea.GetSize().cx,
                clipSourceArea.GetSize().cy,
                DrawSurface,
                clipSourceArea.left,clipSourceArea.top);


			const RasterPoint centerscreen = { ScreenSizeX/2, ScreenSizeY/2 };
			DrawMapScale(BackBufferSurface,MapRect,false);
			DrawCrossHairs(BackBufferSurface, centerscreen, MapRect);
			lastdrawwasbitblitted=true;
		} else {
			// THIS IS NOT GOING TO HAPPEN!
			//
			// The map was not dirty, and we are not in fastpanning mode.
			// FastRefresh!  We simply redraw old bitmap.
			//
#ifndef USE_GDI
            ScopeLock Lock(BackBuffer_Mutex);
#endif
            DrawSurface.CopyTo(BackBufferSurface);

			lastdrawwasbitblitted=true;
		}

		// Now we can clear the flag. If it was off already, no problems.
//		OnFastPanning=false;
        MainWindow.Redraw(MapRect);
		continue;

	} else {
		//
		// Else the map wasy dirty, and we must render it..
		// Notice: if we were fastpanning, than the map could not be dirty.
		//

		#if 1 // --------------------- EXPERIMENTAL, CHECK ZOOM IS WORKING IN PNA
		static unsigned lasthere=0;
		// Only for special case: PAN mode, map not dirty (including requests for zooms!)
		// not in the ForceRenderMap run and last time was a real rendering. THEN, at these conditions,
		// we simply redraw old bitmap, for the scope of accelerating touch response.
		// In fact, if we are panning the map while rendering, there would be an annoying delay.
		// This is using lastdrawwasbitblitted
		if (INPAN && !MapDirty && !lastdrawwasbitblitted && !ForceRenderMap && !first_run) {
			// In any case, after 5 seconds redraw all
			if ( (LKHearthBeats-8) >lasthere ) {
				lasthere=LKHearthBeats;
				goto _dontbitblt;
			}
#ifndef USE_GDI
            ScopeLock Lock(BackBuffer_Mutex);
#endif
            DrawSurface.CopyTo(BackBufferSurface);

			const RasterPoint centerscreen = { ScreenSizeX/2, ScreenSizeY/2 };
			DrawMapScale(BackBufferSurface,MapRect,false);
			DrawCrossHairs(BackBufferSurface, centerscreen, MapRect);
            MainWindow.Redraw(MapRect);
			continue;
		}
		#endif // --------------------------
_dontbitblt:
		MapDirty = false;
		PanRefreshed=true;
	} // MapDirty

	lastdrawwasbitblitted=false;
	MapWindow::UpdateInfo(&GPS_INFO, &CALCULATED_INFO);
	RenderMapWindow(DrawSurface, MapRect);

    {
#ifndef USE_GDI
        ScopeLock Lock(BackBuffer_Mutex);
#endif
        if (!ForceRenderMap && !first_run) {
            DrawSurface.CopyTo(BackBufferSurface);
        }

        // Draw cross sight for pan mode, in the screen center,
        // after a full repaint while not fastpanning
        if (mode.AnyPan() && !mode.Is(Mode::MODE_TARGET_PAN) && !OnFastPanning) {
            POINT centerscreen;
            centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2;
            DrawMapScale(BackBufferSurface,MapRect,false);
            DrawCompass(BackBufferSurface, MapRect, DisplayAngle);
            DrawCrossHairs(BackBufferSurface, centerscreen, MapRect);
        }
    }

	UpdateTimeStats(false);

	// we do caching after screen update, to minimise perceived delay
	// UpdateCaches is updating topology bounds when either forced (only here)
	// or because MapWindow::ForceVisibilityScan  is set true.
    const ScreenProjection _Proj;
	UpdateCaches(_Proj, first_run);
	first_run=false;

	ForceRenderMap = false;

	if (ProgramStarted==psInitDone) {
		ProgramStarted = psFirstDrawDone;
	}
    MainWindow.Redraw(MapRect);

  } // Big LOOP

  #if TESTBENCH
  StartupStore(_T("... Thread_Draw terminated\n"));
  #endif
  THREADEXIT = TRUE;

}
Ejemplo n.º 3
0
DWORD MapWindow::DrawThread (LPVOID lpvoid)
{

  FILETIME CreationTime, ExitTime, StartKernelTime, EndKernelTime, StartUserTime, EndUserTime ;


  while ((!ProgramStarted) || (!Initialised)) {
	Sleep(100);
  }

  #if TRACETHREAD
  StartupStore(_T("##############  DRAW threadid=%d\n"),GetCurrentThreadId());
  #endif


  // THREADRUNNING = FALSE;
  THREADEXIT = FALSE;

  // Reset common topology and waypoint label declutter, first init. Done also in other places.
  ResetLabelDeclutter();

  GetClientRect(hWndMapWindow, &MapRect);
  // Default draw area is full screen, no opacity
  DrawRect=MapRect;

  UpdateTimeStats(true);

  
  SetBkMode(hdcDrawWindow,TRANSPARENT);
  SetBkMode(hDCTemp,OPAQUE);
  SetBkMode(hDCMask,OPAQUE);

  // paint draw window black to start
  SelectObject(hdcDrawWindow, GetStockObject(BLACK_PEN));
  Rectangle(hdcDrawWindow,MapRect.left,MapRect.top,
            MapRect.right,MapRect.bottom);

  BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left,
         MapRect.bottom-MapRect.top, 
         hdcDrawWindow, 0, 0, SRCCOPY);

  // This is just here to give fully rendered start screen
  UpdateInfo(&GPS_INFO, &CALCULATED_INFO);
  MapDirty = true;
  UpdateTimeStats(true);

  zoom.RequestedScale(zoom.Scale());
  zoom.ModifyMapScale();
  FillScaleListForEngineeringUnits();
  
  bool lastdrawwasbitblitted=false;
  bool first_run=true;

  // 
  // Big LOOP
  //

  while (!CLOSETHREAD) 
  {
	WaitForSingleObject(drawTriggerEvent, 5000);
	ResetEvent(drawTriggerEvent);
	if (CLOSETHREAD) break; // drop out without drawing

	if ((!THREADRUNNING) || (!GlobalRunning)) {
		Sleep(100);
		continue;
	}

	// This is also occuring on resolution change
	if (LKSW_ReloadProfileBitmaps) {
		#if TESTBENCH
		StartupStore(_T(".... SWITCH: ReloadProfileBitmaps detected\n"));
		#endif
		// This is needed to update resolution change
		GetClientRect(hWndMapWindow, &MapRect);
		DrawRect=MapRect;
		FillScaleListForEngineeringUnits();
		LKUnloadProfileBitmaps();
		LKLoadProfileBitmaps();
		LKUnloadFixedBitmaps();
		LKLoadFixedBitmaps();
		MapWindow::zoom.Reset();

		// This will reset the function for the new ScreenScale
		PolygonRotateShift((POINT*)NULL,0,0,0,DisplayAngle+1);

		// Restart from moving map
		if (MapSpaceMode!=MSM_WELCOME) SetModeType(LKMODE_MAP, MP_MOVING);

		LKSW_ReloadProfileBitmaps=false;
		// These should be better checked. first_run is forcing also cache update for topo.
		ForceRenderMap=true;
		first_run=true;
	}



	GetThreadTimes( hDrawThread, &CreationTime, &ExitTime,&StartKernelTime,&StartUserTime);

	// Until MapDirty is set true again, we shall only repaint the screen. No Render, no calculations, no updates.
	// This is intended for very fast immediate screen refresh.
	//
	// MapDirty is set true by:
	//   - TriggerRedraws()  in calculations thread
	//   - RefreshMap()      in drawthread generally
	//


	extern int XstartScreen, YstartScreen, XtargetScreen, YtargetScreen;
	extern bool OnFastPanning;
	// While we are moving in bitblt mode, ignore RefreshMap requests from LK
	// unless a timeout was triggered by MapWndProc itself.
	if (OnFastPanning) {
		MapDirty=false;
	} 

	// We must check if we are on FastPanning, because we may be in pan mode even while
	// the menu buttons are active and we are using them, accessing other functions.
	// In that case, without checking OnFastPanning, we would fall back here and repaint
	// with bitblt everytime, while instead we were asked a simple fastrefresh!
	//
	// Notice: we could be !MapDirty without OnFastPanning, of course!
	//
	if (!MapDirty && !ForceRenderMap && OnFastPanning && !first_run) {
		
		if (!mode.Is(Mode::MODE_TARGET_PAN) && mode.Is(Mode::MODE_PAN)) {

			int fromX=0, fromY=0;

			fromX=XstartScreen-XtargetScreen;
			fromY=YstartScreen-YtargetScreen;

			BitBlt(hdcScreen, 0, 0, 
				MapRect.right-MapRect.left, 
				MapRect.bottom-MapRect.top, 
				hdcDrawWindow, 0, 0, WHITENESS);


			BitBlt(hdcScreen, 0, 0,
				MapRect.right-MapRect.left,
				MapRect.bottom-MapRect.top, 
				hdcDrawWindow, 
				fromX,fromY, 				// source
				SRCCOPY);

			POINT centerscreen;
			centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2;
			DrawMapScale(hdcScreen,MapRect,false);
			DrawCrossHairs(hdcScreen, centerscreen, MapRect);
			lastdrawwasbitblitted=true;
		} else {
			// THIS IS NOT GOING TO HAPPEN!
			//
			// The map was not dirty, and we are not in fastpanning mode.
			// FastRefresh!  We simply redraw old bitmap. 
			//
			BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left,
				MapRect.bottom-MapRect.top, 
				hdcDrawWindow, 0, 0, SRCCOPY);

			lastdrawwasbitblitted=true;
		}

		// Now we can clear the flag. If it was off already, no problems.
		OnFastPanning=false;
		continue;

	} else {
		//
		// Else the map wasy dirty, and we must render it..
		// Notice: if we were fastpanning, than the map could not be dirty.
		//

		#if 1 // --------------------- EXPERIMENTAL, CHECK ZOOM IS WORKING IN PNA
		static double lasthere=0;
		// Only for special case: PAN mode, map not dirty (including requests for zooms!)
		// not in the ForceRenderMap run and last time was a real rendering. THEN, at these conditions,
		// we simply redraw old bitmap, for the scope of accelerating touch response.
		// In fact, if we are panning the map while rendering, there would be an annoying delay.
		// This is using lastdrawwasbitblitted
		if (INPAN && !MapDirty && !lastdrawwasbitblitted && !ForceRenderMap && !first_run) {
			// In any case, after 5 seconds redraw all
			if ( (LKHearthBeats-8) >lasthere ) {
				lasthere=LKHearthBeats;
				goto _dontbitblt;
			}
			BitBlt(hdcScreen, 0, 0, MapRect.right-MapRect.left,
				MapRect.bottom-MapRect.top, 
				hdcDrawWindow, 0, 0, SRCCOPY);

			POINT centerscreen;
			centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2;
			DrawMapScale(hdcScreen,MapRect,false);
			DrawCrossHairs(hdcScreen, centerscreen, MapRect);
			continue;
		} 
		#endif // --------------------------
_dontbitblt:
		MapDirty = false;
		PanRefreshed=true;
	} // MapDirty

	lastdrawwasbitblitted=false;
	MapWindow::UpdateInfo(&GPS_INFO, &CALCULATED_INFO);

	RenderMapWindow(MapRect);
    
	if (!ForceRenderMap && !first_run) {
		BitBlt(hdcScreen, 0, 0, 
			MapRect.right-MapRect.left,
			MapRect.bottom-MapRect.top, 
			hdcDrawWindow, 0, 0, SRCCOPY);
		InvalidateRect(hWndMapWindow, &MapRect, false);
	}

	// Draw cross sight for pan mode, in the screen center, 
	// after a full repaint while not fastpanning
	if (mode.AnyPan() && !mode.Is(Mode::MODE_TARGET_PAN) && !OnFastPanning) {
		POINT centerscreen;
		centerscreen.x=ScreenSizeX/2; centerscreen.y=ScreenSizeY/2;
		DrawMapScale(hdcScreen,MapRect,false);
		DrawCompass(hdcScreen, MapRect, DisplayAngle);
		DrawCrossHairs(hdcScreen, centerscreen, MapRect);
	}

	UpdateTimeStats(false);

	// we do caching after screen update, to minimise perceived delay
	// UpdateCaches is updating topology bounds when either forced (only here)
	// or because MapWindow::ForceVisibilityScan  is set true.
	UpdateCaches(first_run);
	first_run=false;

	ForceRenderMap = false;

	if (ProgramStarted==psInitDone) {
		ProgramStarted = psFirstDrawDone;
	}

	if ( (GetThreadTimes( hDrawThread, &CreationTime, &ExitTime,&EndKernelTime,&EndUserTime)) == 0) {
		Cpu_Draw=9999;
	} else {
		Cpustats(&Cpu_Draw,&StartKernelTime, &EndKernelTime, &StartUserTime, &EndUserTime);
	}
    
  } // Big LOOP

  #if TESTBENCH
  StartupStore(_T("... Thread_Draw terminated\n"));
  #endif
  THREADEXIT = TRUE;
  return 0;
}