var
  framecount,
  swb_framecount: integer;
  swb_accum: double = 0;

  procedure MeasureFps;
  var
    n: double;
    dt: double;
  begin
    inc(framecount);
    if not MotherState.SuspendSwbMeasurement then begin
      inc (swb_framecount);
      swb_accum+= MotherState.LastSwapBuffersDuration;
    end;
    n:= Second();
    if prevfpssec =0 then prevfpssec:= n;
    dt:= (n - prevfpssec);
    if dt < FPS_MEASURING_INTERVAL then exit;

    MotherState.FPS:= framecount / max(dt, 0.0011);

    //Must suspend measurement during operations like creating FBOs to avoid a feedback loop
    if swb_framecount > 0 then MotherState.AverageSwapBuffersDuration:= swb_accum / swb_framecount;

    swb_accum:= 0;
    prevfpssec:= n;
    framecount:=0;
    swb_framecount:= 0;
  end;


  procedure InitFpsCounter;
  var
    par: TFpsCounterParam;
    parn: string;
  begin
    for par:= low(TFpsCounterParam) to high (TFpsCounterParam) do begin
      parn:= GetEnumName(typeinfo(TFpsCounterParam), ord(par));
      parn:= copy(parn, 4 + 1, length(parn) - 4);
      if Config.Bool['FpsCounter', parn]
        then MotherState.FpsCounterParams += [par]
    end;
  end;

  procedure RenderFpsCounter;
  var
    fit: TStringFitRec;
    left, top: integer;
    zoomX, zoomY: GLfloat;
    ws: widestring;
    par: TFpsCounterParam;
  begin
    if not DoShowFps then exit;
    //fps:xxx
    // qf:xxx
    _cgeffFitStringIntoRectangle (
      FPS_COUNTER_MAX_FONT_SIZE, 9, 1,
      round(FPS_COUNTER_SIZE * (MotherState.DisplayWidth + MotherState.DisplayHeight) / 2),
      100,  @fit);
    glColor4f(1, 1, 1, 1);
    _cgeffSetRenderState (false);
    left:= MotherState.DisplayWidth - fit.ActualWidth - 4;
    top:= MotherState.DisplayHeight - fit.ActualHeight;
    if MotherState.FPS > 999.0 then MotherState.FPS:=999.0;
    if MotherState.QF > QF_MAX then MotherState.QF:= QF_MAX;
    for par:= low(TFpsCounterParam) to high (TFpsCounterParam) do
      if par in MotherState.FpsCounterParams then begin
        case par of
          fcp_QualityFactor: ws:=format('  qf:%4d',[round(MotherState.QF)]);
          fcp_FramesPerSecond: ws:=format('  fps:%3d',[round(MotherState.FPS)]);
          fcp_RdtscFrequency: ws:=format('cpu:%.3f',[MotherState.RdtscFrequency / 1000000000]);
          fcp_SwapBuffersTime: ws:=format('swb:%.3f',[MotherState.AverageSwapBuffersDuration / 1000]);
        else
          Die(MI_ERROR_PROGRAMMER_NO_BAKA, [
           'fps counter render not implemented for '
            + GetEnumName(typeinfo(TFpsCounterParam), ord(par))]);
        end;
        _cgeffRenderString (@fit, left, top, PWideChar(ws));
        top-= fit.ActualHeight;
      end;
    if _dsay <> '' then _cgeffRenderString (@fit, 5, top, PWideChar(_dsay));
    _dsay:='';
  end;

