예제 #1
0
파일: Timer.cpp 프로젝트: whztt07/globe
GLB_FORCEINLINE void Timer::getCorrectPerformanceValue (int64& nPerfCountElapsed) const
{
  uint32 uiTicksElapsed;
  uint32 uiPerfCountElapsedMilli;
  int32  nLeapTest;

  // get performance counter value
  this->getPerformanceCount(nPerfCountElapsed, uiTicksElapsed);

  // prepare a workaround to compensate a potential performance counter leap
  nPerfCountElapsed       -= m_nStart;
  uiPerfCountElapsedMilli  = uint32(nPerfCountElapsed * 1000 / m_nFrequency);

  GLB_ASSERT((nPerfCountElapsed * 1000 / m_nFrequency) <= (LONGLONG)std::numeric_limits<uint32>::max());
  GLB_ASSERT(uiPerfCountElapsedMilli <= (uint32)std::numeric_limits<int32>::max());
  GLB_ASSERT(uiTicksElapsed          <= (uint32)std::numeric_limits<int32>::max());

  // if too great leap is detected, adjust start time and update state
  // accordingly before return
  nLeapTest = (int32)uiPerfCountElapsedMilli - (int32)uiTicksElapsed;
  if ((nLeapTest < -c_nMaxLeapThreshold) || (nLeapTest > c_nMaxLeapThreshold))
  {
    LONGLONG nUpdate = std::min<LONGLONG>(LONGLONG(nLeapTest * m_nFrequency / 1000), (nPerfCountElapsed - m_nLastPerfCountElapsed));

#ifdef GLB_DEBUG
    //GLB_LOGWARN("Performance Counter leap detected (%d ms) !", nLeapTest);
#endif

    m_nStart          += nUpdate;
    nPerfCountElapsed -= nUpdate;
  }

  // update state
  m_nLastPerfCountElapsed = nPerfCountElapsed;
}
예제 #2
0
//---------------------------------------------------------------------------
bool FileIterator::openDir (const char* pszDirectory, FileIterator::FileInfo& infoFirst)
{
  this->close();

  GLB_ASSERT(pszDirectory);
  if (!pszDirectory)
    return false;
  GLB_ASSERT(pszDirectory[0]);
  if (!pszDirectory[0])
    return false;

  m_strDir = pszDirectory;
  while (m_strDir.pathHasTrailingSeparator())
    m_strDir.erase(-1);

  if (!FileSystem::isDirectory(m_strDir))
  {
    m_strDir.clear();
    return false;
  }

  if ((infoFirst.fQueryFlags & QUERY_DIRS_AND_FILES) == 0)
    infoFirst.fQueryFlags |= QUERY_DIRS_AND_FILES;

  if (!this->getNext(infoFirst))
  {
    m_bEmpty = true;
    return false;
  }

  return true;
}
예제 #3
0
파일: Timer.cpp 프로젝트: whztt07/globe
//---------------------------------------------------------------------------
void Timer::reset (void)
{
  #if defined(GLB_PLATFORM_WINDOWS)
  {
    if (g_nPerfCounter > 0)
    {
      DWORD     dwProcessAffinityMask;
      DWORD     dwSystemAffinityMask;
      DWORD_PTR dwOldThreadAffinityMask;
      HANDLE    hThread;

      // get current process affinity with processor cores
      ::GetProcessAffinityMask(::GetCurrentProcess(), (PDWORD_PTR)&dwProcessAffinityMask, (PDWORD_PTR)&dwSystemAffinityMask);

      // lazy init for the timer affinity mask
      // this is a common trick to find the first core used by the current process
      if (!m_dwTimerAffinityMask)
      {
        m_dwTimerAffinityMask = 1;
        while (!(m_dwTimerAffinityMask & dwProcessAffinityMask))
          m_dwTimerAffinityMask <<= 1;
      }

      // setup our affinity to the desired processor core
      hThread = ::GetCurrentThread();
      dwOldThreadAffinityMask = ::SetThreadAffinityMask(hThread, m_dwTimerAffinityMask);

      // init timer by getting frequency and start time
      (void)::QueryPerformanceFrequency((LARGE_INTEGER*)&m_nFrequency);
      (void)::QueryPerformanceCounter((LARGE_INTEGER*)&m_nStart);
      m_dwStartTicks = g_pfnTimeGetTime();

      // reset affinity to be compliant with the calling environment
      (void)::SetThreadAffinityMask(hThread, dwOldThreadAffinityMask);

      // if frequency is not bound in a 32bit word, we'll get erroneous values
      // from Timer::Get*32() methods
      GLB_ASSERT(m_nFrequency <= (int64)std::numeric_limits<uint32>::max());

      // reset other members
      m_nLastPerfCountElapsed = 0;
    }
    else
    {
      GLB_ASSERT(g_pfnTimeGetTime);
      m_dwStartTicks = g_pfnTimeGetTime();
    }
  }
  #elif defined(GLB_PLATFORM_LINUX)
  {
    gettimeofday(&m_tvStart, NULL);
  }
  #endif
}
예제 #4
0
파일: Timer.cpp 프로젝트: whztt07/globe
//---------------------------------------------------------------------------
uint32 Timer::getMilliseconds32 (void) const
{
  #if defined(GLB_PLATFORM_WINDOWS)
  {
    if (g_nPerfCounter > 0)
    {
      uint32 uiPerfCountElapsedMilli;
      this->getCorrectPerformanceValueMilli(uiPerfCountElapsedMilli);
      return uiPerfCountElapsedMilli;
    }
    else
    {
      DWORD dwTime;

      dwTime = g_pfnTimeGetTime();
      GLB_ASSERT(dwTime > m_dwStartTicks);

      return (dwTime - m_dwStartTicks);
    }
  }
  #elif defined(GLB_PLATFORM_LINUX)
  {
	  struct timeval tvNow;
    uint32 uiElapsed;

    gettimeofday(&tvNow, NULL);

    uiElapsed  = uint32(tvNow.tv_sec - m_tvStart.tv_sec) * 1000;
    uiElapsed += uint32(tvNow.tv_usec - m_tvStart.tv_usec) / 1000;

    return uiElapsed;
  }
  #endif
}
예제 #5
0
파일: Texture.cpp 프로젝트: whztt07/globe
//---------------------------------------------------------------------------
D3DSURFACE_DESC Texture::getLevelDesc (uint uiLevel/*=0*/)
{
  D3DSURFACE_DESC d3dSurfDesc;

  GLB_ASSERT(this->getRef());
  GLB_DXTEST(this->getRef()->GetLevelDesc(uiLevel, &d3dSurfDesc));

  return d3dSurfDesc;
}
예제 #6
0
파일: Surface.cpp 프로젝트: whztt07/globe
//---------------------------------------------------------------------------
D3DSURFACE_DESC Surface::getDesc (void)
{
  D3DSURFACE_DESC d3dSurfDesc;

  GLB_ASSERT(this->getRef());
  GLB_DXTEST(this->getRef()->GetDesc(&d3dSurfDesc));

  return d3dSurfDesc;
}
예제 #7
0
파일: Timer.cpp 프로젝트: whztt07/globe
GLB_FORCEINLINE void Timer::getPerformanceCount (int64& nOutPerfCount, uint32& uiOutTicksElapsed) const
{
  HANDLE    hThread = ::GetCurrentThread();
  DWORD_PTR dwOldThreadAffinityMask;

  GLB_ASSERT(g_nPerfCounter > 0);
  GLB_ASSERT(g_pfnTimeGetTime);

  dwOldThreadAffinityMask = ::SetThreadAffinityMask(hThread, m_dwTimerAffinityMask);

  (void)::QueryPerformanceCounter((LARGE_INTEGER*)&nOutPerfCount);
  uiOutTicksElapsed = g_pfnTimeGetTime();

  (void)::SetThreadAffinityMask(hThread, dwOldThreadAffinityMask);

  GLB_ASSERT(uiOutTicksElapsed > m_dwStartTicks);
  uiOutTicksElapsed -= m_dwStartTicks;
}
예제 #8
0
파일: Texture.cpp 프로젝트: whztt07/globe
//---------------------------------------------------------------------------
Surface Texture::getLevel (uint uiLevel/*=0*/)
{
  IDirect3DSurface9* pSurf;

  GLB_ASSERT(this->getRef());
  GLB_DXTEST(this->getRef()->GetSurfaceLevel(uiLevel, &pSurf));
  pSurf->Release(); // GetSurfaceLevel() incremented the ref counter

  return Surface(pSurf);
}
예제 #9
0
//---------------------------------------------------------------------------
bool FileIterator::seekToFirst (FileIterator::FileInfo& info)
{
  StringA strDir;

  GLB_ASSERT(this->isOpen());
  if(!this->isOpen())
    return false;

  // the problem :
  // * in the linux implementation, we could simply use the rewinddir()
  //   function to simply seek read pointer to start, but this kind of
  //   behavior is not allowed by the win32 api.
  // * so the only way to get same behavior between multiple platforms is to
  //   close the handle before opening a new one.
  strDir = m_strDir;
  return this->openDir(strDir, info);
}
예제 #10
0
파일: Timer.cpp 프로젝트: whztt07/globe
//---------------------------------------------------------------------------
uint64 Timer::getMicroseconds (void) const
{
  #if defined(GLB_PLATFORM_WINDOWS)
  {
    if (g_nPerfCounter > 0)
    {
      int64 nPerfCountElapsed;

      this->getCorrectPerformanceValue(nPerfCountElapsed);

      // scale by 1000000 in order to get microsecond precision
      nPerfCountElapsed *= 1000000;
      nPerfCountElapsed /= m_nFrequency;

      return nPerfCountElapsed;
    }
    else
    {
      DWORD dwTime;

      dwTime = g_pfnTimeGetTime();
      GLB_ASSERT(dwTime > m_dwStartTicks);

      return uint64(dwTime - m_dwStartTicks) * 1000;
    }
  }
  #elif defined(GLB_PLATFORM_LINUX)
  {
    struct timeval tvNow;
    int64 nElapsed;

    gettimeofday(&tvNow, NULL);

    nElapsed  = int64(tvNow.tv_sec - m_tvStart.tv_sec) * 1000000;
    nElapsed += int64(tvNow.tv_usec - m_tvStart.tv_usec);

    if (nElapsed < 0)
      nElapsed = 0;

    return (uint64)nElapsed;
  }
  #endif
}
예제 #11
0
파일: Timer.cpp 프로젝트: whztt07/globe
//---------------------------------------------------------------------------
float64 Timer::getSecondsFloat64 (void) const
{
  #if defined(GLB_PLATFORM_WINDOWS)
  {
    if (g_nPerfCounter > 0)
    {
      int64 nPerfCountElapsed;
      this->getCorrectPerformanceValue(nPerfCountElapsed);
      return (float64)nPerfCountElapsed / (float64)m_nFrequency;
    }
    else
    {
      DWORD   dwTime;
      float64 rTime;

      dwTime = g_pfnTimeGetTime();
      GLB_ASSERT(dwTime > m_dwStartTicks);

      rTime  = float64(dwTime - m_dwStartTicks);
      rTime *= float64(0.001);

      return rTime;
    }
  }
  #elif defined(GLB_PLATFORM_LINUX)
  {
	  struct timeval tvNow;
    float64 rElapsed;

    gettimeofday(&tvNow, NULL);

    rElapsed  = float64(tvNow.tv_sec - m_tvStart.tv_sec);
    rElapsed += float64(0.000001) * float64(tvNow.tv_usec - m_tvStart.tv_usec);

    if (rElapsed < float64(0.0))
      rElapsed = float64(0.0);

    return rElapsed;
  }
  #endif
}
예제 #12
0
//---------------------------------------------------------------------------
bool FileIterator::getNext (FileIterator::FileInfo& info)
{
  GLB_ASSERT(this->isOpen());
  if (!this->isOpen() || m_bEmpty)
    return false;

  info.fQueryFlags |= QUERY_TYPE;

  while (1)
  {
    if (!this->getNextImpl(info))
      return false;

    if (info.eType == TYPE_DIRECTORY && (info.fQueryFlags & QUERY_DIRS))
      return true;
    else if (info.eType != TYPE_DIRECTORY && (info.fQueryFlags & QUERY_FILES))
      return true;
  }

  return true;
}
예제 #13
0
파일: sampler.c 프로젝트: bsurmanski/glb
GLBSampler* glbCreateSampler (int *errcode_ret)
{
    int errcode;
    GLBSampler *sampler = malloc(sizeof(GLBSampler));
    GLB_ASSERT(sampler, GLB_OUT_OF_MEMORY, ERROR);

    sampler->refcount = 1;
    sampler->magfilter = GLB_LINEAR;
    sampler->minfilter = GLB_LINEAR;
    sampler->minlod = -1000.0f;
    sampler->maxlod = 1000.0f;
    sampler->wrap_s = GLB_REPEAT;
    sampler->wrap_t = GLB_REPEAT;
    sampler->wrap_r = GLB_REPEAT;
    sampler->compare_mode = GLB_NONE;
    sampler->compare_func = GLB_LEQUAL;

    GLB_SET_ERROR(GLB_SUCCESS);
    return sampler;

ERROR:
    GLB_SET_ERROR(errcode);
    return NULL;
}
예제 #14
0
//---------------------------------------------------------------------------
bool FileIterator::getNextImpl (FileIterator::FileInfo& info)
{
  bool bIsFirst = false;

  #ifdef GLB_PLATFORM_WINDOWS
  {
    WIN32_FIND_DATAA wfd;

    if (m_pHandle == INVALID_HANDLE_VALUE)
    {
      bIsFirst = true;

      m_strDir.pathAppend("*");

      m_pHandle = ::FindFirstFileA(m_strDir.c_str(), &wfd);

      if (m_strDir.right(1) == "*")
      {
        m_strDir.erase(-1);
        while (m_strDir.pathHasTrailingSeparator())
          m_strDir.erase(-1);
      }
    }
    else if (!::FindNextFileA(m_pHandle, &wfd))
    {
      _FileIterator_ResetInfo(info);
      return false;
    }

    if (m_pHandle == INVALID_HANDLE_VALUE)
    {
      GLB_LOGERR("Error while trying to iterate in \"%s\" ! Error %lu : %s", m_strDir.c_str(), System::lastError(), System::lastErrorString());
      _FileIterator_ResetInfo(info);
      return false;
    }
    else
    {
      // skip "." and ".." entries
      while (!strcmp((char*)&wfd.cFileName, ".") ||
        !strcmp((char*)&wfd.cFileName, "..") ||
        ((wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) && !(info.fQueryFlags & FileIterator::QUERY_HIDDEN)))
      {
        if (!::FindNextFileA(m_pHandle, &wfd))
        {
          if (bIsFirst)
            m_bEmpty = true; // no valid entry found at all
          _FileIterator_ResetInfo(info);
          return false;
        }
      }

      // FindFirstFile() and FindNextFile() automatically convert non-utc
      // times into utc times
      _FileIterator_MapOsDataToFileInfo(info, m_strDir, wfd, true);
    }
  }
  #else
  {
    struct dirent* pDirEntry;

    if (!m_pHandle)
    {
      bIsFirst = true;

      m_pHandle = opendir(m_strDir.c_str());
      if (!m_pHandle)
      {
        GLB_LOGERROR("Error while trying to iterate in \"%s\" ! Error %lu : %s", m_strDir.c_str(), System::lastError(), System::lastErrorString());
        _FileIterator_ResetInfo(info);
        return false;
      }
    }

    GLB_ASSERT(m_pHandle);
    while ((pDirEntry = readdir((DIR*)m_pHandle)) != NULL)
    {
      if (strcmp((char*)&pDirEntry->d_name, ".") && strcmp((char*)&pDirEntry->d_name, ".."))
      {
        if (pDirEntry->d_name[0] != '.' || (info.fQueryFlags & FileIterator::QUERY_HIDDEN))
          break;
      }
    }

    if (!pDirEntry)
    {
      if (bIsFirst)
        m_bEmpty = true; // no valid entry found at all
      _FileIterator_ResetInfo(info);
      return false;
    }

    _FileIterator_MapOsDataToFileInfo(info, m_strDir, (char*)&pDirEntry->d_name);
  }
  #endif

  return true;
}
예제 #15
0
static void _FileIterator_MapOsDataToFileInfo (FileIterator::FileInfo& info, const StringA& strDir, const char* pszFileName)
{
#if defined(GLB_PLATFORM_CYGWIN)
  #define STATSTRUCT  struct stat
  #define STATFUNC    ::stat
#else
  #define STATSTRUCT  struct stat64
  #define STATFUNC    ::stat64
#endif

  STATSTRUCT stats;

  // name
  info.strName = pszFileName;

  // reset other members first
  info.eType      = FileIterator::TYPE_UNKNOWN;
  info.uiSize     = 0;
  info.nModifTime = 0;

  // get file stats if needed
  if (info.fQueryFlags != 0)
  {
    StringA strFilePath;

    _FileIterator_BuildFilePathIfNeeded(strFilePath, strDir, info.strName);
    if (STATFUNC(strFilePath, &stats) != 0)
    {
      GLB_ASSERT(0); // error while calling stat() from FileIterator !
      return;
    }
  }

  // type
  if ((info.fQueryFlags & FileIterator::QUERY_TYPE) != 0)
  {
    if (S_ISDIR(stats.st_mode))
      info.eType = FileIterator::TYPE_DIRECTORY;
    else if (S_ISREG(stats.st_mode))
      info.eType = FileIterator::TYPE_FILE;
    else if (S_ISLNK(stats.st_mode))
      info.eType = FileIterator::TYPE_SYMLINK;
  }

  // size
  if ((info.fQueryFlags & FileIterator::QUERY_SIZE) != 0)
  {
    GLB_ASSERT(sizeof(info.uiSize) == sizeof(stats.st_size));
    info.uiSize = stats.st_size;
  }

  // modification time
  if ((info.fQueryFlags & FileIterator::QUERY_MODIFTIME) != 0)
  {
    GLB_ASSERT(sizeof(info.nModifTime) == sizeof(stats.st_mtime));
    info.nModifTime = stats.st_mtime;
  }

#undef STATSTRUCT
#undef STATFUNC
}