zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs

now_windows.go (1899B)


      1 // Copyright 2019 The Ebiten Authors
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 package clock
     16 
     17 import (
     18 	"fmt"
     19 	"unsafe"
     20 
     21 	"golang.org/x/sys/windows"
     22 )
     23 
     24 var (
     25 	kernel32 = windows.NewLazySystemDLL("kernel32")
     26 )
     27 
     28 var (
     29 	procQueryPerformanceFrequency = kernel32.NewProc("QueryPerformanceFrequency")
     30 	procQueryPerformanceCounter   = kernel32.NewProc("QueryPerformanceCounter")
     31 )
     32 
     33 func queryPerformanceFrequency() int64 {
     34 	var freq int64
     35 	// TODO: Should the returned value be checked?
     36 	_, _, e := procQueryPerformanceFrequency.Call(uintptr(unsafe.Pointer(&freq)))
     37 	if e != nil && e.(windows.Errno) != 0 {
     38 		panic(fmt.Sprintf("clock: QueryPerformanceFrequency failed: errno: %d", e.(windows.Errno)))
     39 	}
     40 	return freq
     41 }
     42 
     43 func queryPerformanceCounter() int64 {
     44 	var ctr int64
     45 	// TODO: Should the returned value be checked?
     46 	_, _, e := procQueryPerformanceCounter.Call(uintptr(unsafe.Pointer(&ctr)))
     47 	if e != nil && e.(windows.Errno) != 0 {
     48 		panic(fmt.Sprintf("clock: QueryPerformanceCounter failed: errno: %d", e.(windows.Errno)))
     49 	}
     50 	return ctr
     51 }
     52 
     53 var (
     54 	freq    = queryPerformanceFrequency()
     55 	initCtr = queryPerformanceCounter()
     56 )
     57 
     58 func now() int64 {
     59 	// Use the time duration instead of the current counter to avoid overflow.
     60 	duration := queryPerformanceCounter() - initCtr
     61 
     62 	// Use float64 not to overflow int64 values (#862).
     63 	return int64(float64(duration) / float64(freq) * 1e9)
     64 }