gpu, io/router, op: use f32.Affine2D instead of op.TransformOp for transforms

Encode TransformOp as an Affince2D matrix instead and use that in gpu and io transform handling.
There are no changes to user facing API and so far only the offset part of the matrix is used.

This patch is a step towards full affine transformations.

Signed-off-by: Viktor <viktor.ogeman@gmail.com>
This commit is contained in:
Viktor
2020-06-20 23:29:50 +02:00
committed by Elias Naur
parent e7bc1a4553
commit b247395c62
5 changed files with 32 additions and 18 deletions
+3 -3
View File
@@ -69,7 +69,7 @@ type drawOps struct {
type drawState struct {
clip f32.Rectangle
t op.TransformOp
t f32.Affine2D
cpath *pathOp
rect bool
z int
@@ -691,8 +691,8 @@ loop:
case opconst.TypeProfile:
d.profile = true
case opconst.TypeTransform:
dop := ops.DecodeTransformOp(encOp.Data)
state.t = state.t.Multiply(op.TransformOp(dop))
dop := ops.DecodeTransform(encOp.Data)
state.t = state.t.Mul(dop)
case opconst.TypeAux:
aux = encOp.Data[opconst.TypeAuxLen:]
auxKey = encOp.Key
+1 -1
View File
@@ -31,7 +31,7 @@ const (
const (
TypeMacroLen = 1 + 4 + 4
TypeCallLen = 1 + 4 + 4
TypeTransformLen = 1 + 4*2
TypeTransformLen = 1 + 4*6
TypeLayerLen = 1
TypeRedrawLen = 1 + 8
TypeImageLen = 1 + 4*4
+16 -7
View File
@@ -8,7 +8,6 @@ import (
"gioui.org/f32"
"gioui.org/internal/opconst"
"gioui.org/op"
)
const QuadSize = 4 * 2 * 3
@@ -38,13 +37,23 @@ func DecodeQuad(d []byte) (q Quad) {
return
}
func DecodeTransformOp(d []byte) op.TransformOp {
bo := binary.LittleEndian
func DecodeTransform(d []byte) (t f32.Affine2D) {
if opconst.OpType(d[0]) != opconst.TypeTransform {
panic("invalid op")
}
return op.TransformOp{}.Offset(f32.Point{
X: math.Float32frombits(bo.Uint32(d[1:])),
Y: math.Float32frombits(bo.Uint32(d[5:])),
})
if len(d) < 1+6*4 {
panic("too short buffer")
}
return decodeAffine2D(d[1:])
}
func decodeAffine2D(data []byte) f32.Affine2D {
bo := binary.LittleEndian
a := math.Float32frombits(bo.Uint32(data))
b := math.Float32frombits(bo.Uint32(data[4*1:]))
c := math.Float32frombits(bo.Uint32(data[4*2:]))
d := math.Float32frombits(bo.Uint32(data[4*3:]))
e := math.Float32frombits(bo.Uint32(data[4*4:]))
f := math.Float32frombits(bo.Uint32(data[4*5:]))
return f32.NewAffine2D(a, b, c, d, e, f)
}
+5 -5
View File
@@ -56,7 +56,7 @@ type areaOp struct {
}
type areaNode struct {
trans op.TransformOp
trans f32.Affine2D
next int
area areaOp
}
@@ -68,7 +68,7 @@ const (
areaEllipse
)
func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t op.TransformOp, area, node int, pass bool) {
func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t f32.Affine2D, area, node int, pass bool) {
for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
switch opconst.OpType(encOp.Data[0]) {
case opconst.TypePush:
@@ -90,8 +90,8 @@ func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t o
})
node = len(q.hitTree) - 1
case opconst.TypeTransform:
dop := ops.DecodeTransformOp(encOp.Data)
t = t.Multiply(op.TransformOp(dop))
dop := ops.DecodeTransform(encOp.Data)
t = t.Mul(dop)
case opconst.TypePointerInput:
op := decodePointerInputOp(encOp.Data, encOp.Refs)
q.hitTree = append(q.hitTree, hitNode{
@@ -175,7 +175,7 @@ func (q *pointerQueue) Frame(root *op.Ops, events *handlerEvents) {
q.hitTree = q.hitTree[:0]
q.areas = q.areas[:0]
q.reader.Reset(root)
q.collectHandlers(&q.reader, events, op.TransformOp{}, -1, -1, false)
q.collectHandlers(&q.reader, events, f32.Affine2D{}, -1, -1, false)
for k, h := range q.handlers {
if !h.active {
q.dropHandlers(events, k)
+7 -2
View File
@@ -290,8 +290,13 @@ func (t TransformOp) Add(o *Ops) {
data := o.Write(opconst.TypeTransformLen)
data[0] = byte(opconst.TypeTransform)
bo := binary.LittleEndian
bo.PutUint32(data[1:], math.Float32bits(t.offset.X))
bo.PutUint32(data[5:], math.Float32bits(t.offset.Y))
// write it out as an affine matrix although we only support offset yet
bo.PutUint32(data[1:], math.Float32bits(1.0))
bo.PutUint32(data[1+4*1:], math.Float32bits(0))
bo.PutUint32(data[1+4*2:], math.Float32bits(t.offset.X))
bo.PutUint32(data[1+4*3:], math.Float32bits(0))
bo.PutUint32(data[1+4*4:], math.Float32bits(1))
bo.PutUint32(data[1+4*5:], math.Float32bits(t.offset.Y))
}
func (s *stack) push() stackID {