From b247395c6259163cd0ca910cd55401d0e31919c4 Mon Sep 17 00:00:00 2001 From: Viktor Date: Sat, 20 Jun 2020 23:29:50 +0200 Subject: [PATCH] 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 --- gpu/gpu.go | 6 +++--- internal/opconst/ops.go | 2 +- internal/ops/ops.go | 23 ++++++++++++++++------- io/router/pointer.go | 10 +++++----- op/op.go | 9 +++++++-- 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/gpu/gpu.go b/gpu/gpu.go index 334f03a4..0cb78a4a 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -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 diff --git a/internal/opconst/ops.go b/internal/opconst/ops.go index aca341f9..62365b8f 100644 --- a/internal/opconst/ops.go +++ b/internal/opconst/ops.go @@ -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 diff --git a/internal/ops/ops.go b/internal/ops/ops.go index 80994e17..721f4628 100644 --- a/internal/ops/ops.go +++ b/internal/ops/ops.go @@ -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) } diff --git a/io/router/pointer.go b/io/router/pointer.go index ec3bb397..0d0977f6 100644 --- a/io/router/pointer.go +++ b/io/router/pointer.go @@ -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) diff --git a/op/op.go b/op/op.go index 82f1457a..3aafbc33 100644 --- a/op/op.go +++ b/op/op.go @@ -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 {