wm/vend/xgbutil/_examples/image-speed/main.go

132 lines
3.3 KiB
Go

//This demonstration shows drawing entire generated images to an x window
//and calculating the speed of the generation and the drawing operations
//It should be noted that redrawing the entire image is inefficient, this demo
//was made to show me how fast I could draw to the windows with this method.
package main
import (
"github.com/jezek/xgb/xproto"
"github.com/jezek/xgbutil"
"github.com/jezek/xgbutil/keybind"
"github.com/jezek/xgbutil/xevent"
"github.com/jezek/xgbutil/xgraphics"
"github.com/jezek/xgbutil/xwindow"
"image"
"log"
"time"
)
func main() {
X, err := xgbutil.NewConn()
if err != nil {
log.Println(err)
return
}
//Initialize the keybind package
keybind.Initialize(X)
//Create a window
win, err := xwindow.Generate(X)
if err != nil {
log.Fatalf("Could not generate a new window X id: %s", err)
}
win.Create(X.RootWin(), 0, 0, 1024, 768, xproto.CwBackPixel, 0x606060ff)
// Listen for Key{Press,Release} events.
win.Listen(xproto.EventMaskKeyPress, xproto.EventMaskKeyRelease)
// Map the window. This is what makes it on the screen
win.Map()
//Make a ...callback... for the events and connect
xevent.KeyPressFun(
func(X *xgbutil.XUtil, e xevent.KeyPressEvent) {
modStr := keybind.ModifierString(e.State)
keyStr := keybind.LookupString(X, e.State, e.Detail)
if len(modStr) > 0 {
log.Printf("Key: %s-%s\n", modStr, keyStr)
} else {
log.Println("Key:", keyStr)
}
if keybind.KeyMatch(X, "Escape", e.State, e.Detail) {
if e.State&xproto.ModMaskControl > 0 {
log.Println("Control-Escape detected. Quitting...")
xevent.Quit(X)
}
}
}).Connect(X, win.Id)
//So here i'm going to try to make a image..'
img := xgraphics.New(X, image.Rect(0, 0, 1024, 768))
err = img.XSurfaceSet(win.Id)
if err != nil {
log.Printf("Error while setting window surface to image %d: %s\n",
win, err)
} else {
log.Printf("Window %d surface set to image OK\n", win)
}
// I /think/ XDraw actually sends data to server?
img.XDraw()
// I /think/ XPaint tells the server to paint image to window
img.XPaint(win.Id)
//Start the routine that updates the window
go updater(img, win)
//This seems to start a main loop for listening to xevents
xevent.Main(X)
}
func updater(img *xgraphics.Image, win *xwindow.Window) {
//We keep track of times based on 1024 frames
frame := 0
start := time.Now()
var genStart, drawStart time.Time
var genTotal, drawTotal time.Duration
for {
frame = frame + 1
if frame > 1024 {
frame = 0
log.Printf("Time elapsed: %s\n", time.Now().Sub(start))
log.Printf("Time generate: %s\n", genTotal)
log.Printf("Time drawing: %s\n", drawTotal)
start = time.Now()
drawTotal, genTotal = 0, 0
}
genStart = time.Now()
var x, y, i int
for y = 0; y < 768; y++ {
//set last pixel back to black
img.SetBGRA(frame-1, y, xgraphics.BGRA{0, 0, 0, 255})
for i = 0; i < 10; i++ {
x = i + frame
if x > 1024 {
x = 1024
}
img.SetBGRA(x, y, xgraphics.BGRA{0, 0, 255, 255})
}
}
genTotal += time.Now().Sub(genStart)
drawStart = time.Now()
//hopefully using checked will block us from drawing again before x
//draws although XDraw might block anyway, we can check for an error
//here
err := img.XDrawChecked()
if err != nil {
log.Println(err)
return
}
//img.XDraw()
img.XPaint(win.Id)
drawTotal += time.Now().Sub(drawStart)
}
}