~eliasnaur/gio

00a87f542dcbc255d05a468b41d5c07a8e402386 — Elias Naur 2 years ago 0061c73
ui: introduce OpColor, a specialized OpImage for uniform colors

To avoid allocating an image.Image for OpImage.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
3 files changed, 45 insertions(+), 1 deletions(-)

M ui/app/internal/gpu/gpu.go
M ui/draw/draw.go
M ui/internal/ops/ops.go
M ui/app/internal/gpu/gpu.go => ui/app/internal/gpu/gpu.go +13 -1
@@ 5,6 5,7 @@ package gpu
import (
	"fmt"
	"image"
	"image/color"
	"math"
	"runtime"
	"strings"


@@ 70,6 71,8 @@ type drawOps struct {
	// Current OpImage image and rect, if any.
	img     image.Image
	imgRect image.Rectangle
	// Current OpColor, if any.
	color color.NRGBA
}

type drawState struct {


@@ 693,6 696,11 @@ loop:
				cpath.path = data
				d.pathOps = append(d.pathOps, cpath)
			}
		case ops.TypeColor:
			var op gdraw.OpColor
			op.Decode(data, r.Refs)
			d.img = nil
			d.color = op.Col
		case ops.TypeImage:
			var op gdraw.OpImage
			op.Decode(data, r.Refs)


@@ 756,7 764,11 @@ func expandPathOp(p *pathOp, clip image.Rectangle) {

func (d *drawOps) materialFor(cache *resourceCache, rect f32.Rectangle, off f32.Point, clip image.Rectangle) material {
	var m material
	if uniform, ok := d.img.(*image.Uniform); ok {
	if d.img == nil {
		m.material = materialColor
		m.color = gamma(d.color.RGBA())
		m.opaque = m.color[3] == 1.0
	} else if uniform, ok := d.img.(*image.Uniform); ok {
		m.material = materialColor
		m.color = gamma(uniform.RGBA())
		m.opaque = m.color[3] == 1.0

M ui/draw/draw.go => ui/draw/draw.go +29 -0
@@ 5,6 5,7 @@ package draw
import (
	"encoding/binary"
	"image"
	"image/color"
	"math"

	"gioui.org/ui"


@@ 18,6 19,10 @@ type OpImage struct {
	Rect image.Rectangle
}

type OpColor struct {
	Col color.NRGBA
}

type OpDraw struct {
	Rect f32.Rectangle
}


@@ 57,6 62,30 @@ func (i *OpImage) Decode(data []byte, refs []interface{}) {
	}
}

func (c OpColor) Add(o *ui.Ops) {
	data := make([]byte, ops.TypeColorLen)
	data[0] = byte(ops.TypeColor)
	data[1] = c.Col.R
	data[2] = c.Col.G
	data[3] = c.Col.B
	data[4] = c.Col.A
	o.Write(data)
}

func (c *OpColor) Decode(data []byte, refs []interface{}) {
	if ops.OpType(data[0]) != ops.TypeColor {
		panic("invalid op")
	}
	*c = OpColor{
		Col: color.NRGBA{
			R: data[1],
			G: data[2],
			B: data[3],
			A: data[4],
		},
	}
}

func (d OpDraw) Add(o *ui.Ops) {
	data := make([]byte, ops.TypeDrawLen)
	data[0] = byte(ops.TypeDraw)

M ui/internal/ops/ops.go => ui/internal/ops/ops.go +3 -0
@@ 29,6 29,7 @@ const (
	TypeClip
	TypeImage
	TypeDraw
	TypeColor
	TypePointerHandler
	TypeKeyHandler
	TypeHideInput


@@ 45,6 46,7 @@ const (
	TypeClipLen           = 1 + 4
	TypeImageLen          = 1 + 4 + 4*4
	TypeDrawLen           = 1 + 4*4
	TypeColorLen          = 1 + 4
	TypePointerHandlerLen = 1 + 4 + 4 + 1
	TypeKeyHandlerLen     = 1 + 4 + 1
	TypeHideInputLen      = 1


@@ 61,6 63,7 @@ var typeLengths = [...]int{
	TypeClipLen,
	TypeImageLen,
	TypeDrawLen,
	TypeColorLen,
	TypePointerHandlerLen,
	TypeKeyHandlerLen,
	TypeHideInputLen,