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 { type drawState struct {
clip f32.Rectangle clip f32.Rectangle
t op.TransformOp t f32.Affine2D
cpath *pathOp cpath *pathOp
rect bool rect bool
z int z int
@@ -691,8 +691,8 @@ loop:
case opconst.TypeProfile: case opconst.TypeProfile:
d.profile = true d.profile = true
case opconst.TypeTransform: case opconst.TypeTransform:
dop := ops.DecodeTransformOp(encOp.Data) dop := ops.DecodeTransform(encOp.Data)
state.t = state.t.Multiply(op.TransformOp(dop)) state.t = state.t.Mul(dop)
case opconst.TypeAux: case opconst.TypeAux:
aux = encOp.Data[opconst.TypeAuxLen:] aux = encOp.Data[opconst.TypeAuxLen:]
auxKey = encOp.Key auxKey = encOp.Key
+1 -1
View File
@@ -31,7 +31,7 @@ const (
const ( const (
TypeMacroLen = 1 + 4 + 4 TypeMacroLen = 1 + 4 + 4
TypeCallLen = 1 + 4 + 4 TypeCallLen = 1 + 4 + 4
TypeTransformLen = 1 + 4*2 TypeTransformLen = 1 + 4*6
TypeLayerLen = 1 TypeLayerLen = 1
TypeRedrawLen = 1 + 8 TypeRedrawLen = 1 + 8
TypeImageLen = 1 + 4*4 TypeImageLen = 1 + 4*4
+16 -7
View File
@@ -8,7 +8,6 @@ import (
"gioui.org/f32" "gioui.org/f32"
"gioui.org/internal/opconst" "gioui.org/internal/opconst"
"gioui.org/op"
) )
const QuadSize = 4 * 2 * 3 const QuadSize = 4 * 2 * 3
@@ -38,13 +37,23 @@ func DecodeQuad(d []byte) (q Quad) {
return return
} }
func DecodeTransformOp(d []byte) op.TransformOp { func DecodeTransform(d []byte) (t f32.Affine2D) {
bo := binary.LittleEndian
if opconst.OpType(d[0]) != opconst.TypeTransform { if opconst.OpType(d[0]) != opconst.TypeTransform {
panic("invalid op") panic("invalid op")
} }
return op.TransformOp{}.Offset(f32.Point{ if len(d) < 1+6*4 {
X: math.Float32frombits(bo.Uint32(d[1:])), panic("too short buffer")
Y: math.Float32frombits(bo.Uint32(d[5:])), }
}) 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 { type areaNode struct {
trans op.TransformOp trans f32.Affine2D
next int next int
area areaOp area areaOp
} }
@@ -68,7 +68,7 @@ const (
areaEllipse 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() { for encOp, ok := r.Decode(); ok; encOp, ok = r.Decode() {
switch opconst.OpType(encOp.Data[0]) { switch opconst.OpType(encOp.Data[0]) {
case opconst.TypePush: case opconst.TypePush:
@@ -90,8 +90,8 @@ func (q *pointerQueue) collectHandlers(r *ops.Reader, events *handlerEvents, t o
}) })
node = len(q.hitTree) - 1 node = len(q.hitTree) - 1
case opconst.TypeTransform: case opconst.TypeTransform:
dop := ops.DecodeTransformOp(encOp.Data) dop := ops.DecodeTransform(encOp.Data)
t = t.Multiply(op.TransformOp(dop)) t = t.Mul(dop)
case opconst.TypePointerInput: case opconst.TypePointerInput:
op := decodePointerInputOp(encOp.Data, encOp.Refs) op := decodePointerInputOp(encOp.Data, encOp.Refs)
q.hitTree = append(q.hitTree, hitNode{ 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.hitTree = q.hitTree[:0]
q.areas = q.areas[:0] q.areas = q.areas[:0]
q.reader.Reset(root) 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 { for k, h := range q.handlers {
if !h.active { if !h.active {
q.dropHandlers(events, k) q.dropHandlers(events, k)
+7 -2
View File
@@ -290,8 +290,13 @@ func (t TransformOp) Add(o *Ops) {
data := o.Write(opconst.TypeTransformLen) data := o.Write(opconst.TypeTransformLen)
data[0] = byte(opconst.TypeTransform) data[0] = byte(opconst.TypeTransform)
bo := binary.LittleEndian bo := binary.LittleEndian
bo.PutUint32(data[1:], math.Float32bits(t.offset.X)) // write it out as an affine matrix although we only support offset yet
bo.PutUint32(data[5:], math.Float32bits(t.offset.Y)) 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 { func (s *stack) push() stackID {