removed opaque and deleted flags from backend, deleted state is now maintained in frontend

This commit is contained in:
Thomas Friedel 2019-02-27 16:05:46 +01:00
parent ba8238ba66
commit 22c3c25d8e
6 changed files with 41 additions and 91 deletions

View file

@ -89,15 +89,11 @@ type GradientStop struct {
type LinearGradient interface {
Delete()
IsDeleted() bool
IsOpaque() bool
Replace(data Gradient)
}
type RadialGradient interface {
Delete()
IsDeleted() bool
IsOpaque() bool
Replace(data Gradient)
}
@ -106,7 +102,5 @@ type Image interface {
Height() int
Size() (w, h int)
Delete()
IsDeleted() bool
Replace(src image.Image) error
IsOpaque() bool
}

View file

@ -27,15 +27,13 @@ type gradient struct {
b *GoGLBackend
tex uint32
loaded bool
deleted bool
opaque bool
}
func (b *GoGLBackend) LoadLinearGradient(data backendbase.Gradient) backendbase.LinearGradient {
b.activate()
lg := &LinearGradient{
gradient: gradient{b: b, opaque: true},
gradient: gradient{b: b},
}
gl.GenTextures(1, &lg.tex)
gl.ActiveTexture(gl.TEXTURE0)
@ -57,7 +55,7 @@ func (b *GoGLBackend) LoadRadialGradient(data backendbase.Gradient) backendbase.
b.activate()
rg := &RadialGradient{
gradient: gradient{b: b, opaque: true},
gradient: gradient{b: b},
}
gl.GenTextures(1, &rg.tex)
gl.ActiveTexture(gl.TEXTURE0)
@ -80,12 +78,8 @@ func (g *gradient) Delete() {
g.b.activate()
gl.DeleteTextures(1, &g.tex)
g.deleted = true
}
func (g *gradient) IsDeleted() bool { return g.deleted }
func (g *gradient) IsOpaque() bool { return g.opaque }
func (lg *LinearGradient) Replace(data backendbase.Gradient) { lg.load(data) }
func (rg *RadialGradient) Replace(data backendbase.Gradient) { rg.load(data) }

View file

@ -15,8 +15,6 @@ type Image struct {
b *GoGLBackend
w, h int
tex uint32
deleted bool
opaque bool
flip bool
}
@ -38,11 +36,9 @@ func (b *GoGLBackend) LoadImage(src image.Image) (backendbase.Image, error) {
img.b = b
runtime.SetFinalizer(img, func(img *Image) {
if !img.deleted {
b.glChan <- func() {
gl.DeleteTextures(1, &img.tex)
}
}
})
return img, nil
@ -74,19 +70,7 @@ func loadImage(src image.Image, tex uint32) (*Image, error) {
}
func loadImageRGBA(src *image.RGBA, tex uint32) (*Image, error) {
img := &Image{tex: tex, w: src.Bounds().Dx(), h: src.Bounds().Dy(), opaque: true}
checkOpaque:
for y := 0; y < img.h; y++ {
off := src.PixOffset(0, y) + 3
for x := 0; x < img.w; x++ {
if src.Pix[off] < 255 {
img.opaque = false
break checkOpaque
}
off += 4
}
}
img := &Image{tex: tex, w: src.Bounds().Dx(), h: src.Bounds().Dy()}
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
@ -147,7 +131,7 @@ func loadImageGray(src *image.Gray, tex uint32) (*Image, error) {
}
func loadImageConverted(src image.Image, tex uint32) (*Image, error) {
img := &Image{tex: tex, w: src.Bounds().Dx(), h: src.Bounds().Dy(), opaque: true}
img := &Image{tex: tex, w: src.Bounds().Dx(), h: src.Bounds().Dy()}
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
@ -161,9 +145,6 @@ func loadImageConverted(src image.Image, tex uint32) (*Image, error) {
ir, ig, ib, ia := src.At(x, y).RGBA()
r, g, b, a := uint8(ir>>8), uint8(ig>>8), uint8(ib>>8), uint8(ia>>8)
data = append(data, r, g, b, a)
if a < 255 {
img.opaque = false
}
}
}
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(img.w), int32(img.h), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Ptr(&data[0]))
@ -192,13 +173,8 @@ func (img *Image) Delete() {
img.b.activate()
gl.DeleteTextures(1, &img.tex)
img.deleted = true
}
// IsDeleted returns true if the Delete function has been
// called on this image
func (img *Image) IsDeleted() bool { return img.deleted }
// Replace replaces the image with the new one
func (img *Image) Replace(src image.Image) error {
img.b.activate()
@ -214,10 +190,6 @@ func (img *Image) Replace(src image.Image) error {
return nil
}
// IsOpaque returns true if all pixels in the image
// have a full alpha value
func (img *Image) IsOpaque() bool { return img.opaque }
func (b *GoGLBackend) DrawImage(dimg backendbase.Image, sx, sy, sw, sh float64, pts [4][2]float64, alpha float64) {
b.activate()

View file

@ -226,19 +226,6 @@ func (cv *Canvas) parseStyle(value ...interface{}) drawStyle {
return style
}
func (s *drawStyle) isOpaque() bool {
if lg := s.linearGradient; lg != nil {
return lg.opaque
}
if rg := s.radialGradient; rg != nil {
return rg.opaque
}
if img := s.image; img != nil {
return img.img.IsOpaque()
}
return s.color.A >= 255
}
func (cv *Canvas) backendFillStyle(s *drawStyle, alpha float64) backendbase.FillStyle {
stl := backendbase.FillStyle{Color: s.color}
alpha *= cv.state.globalAlpha

View file

@ -68,13 +68,27 @@ func (cv *Canvas) CreateRadialGradient(x0, y0, r0, x1, y1, r1 float64) *RadialGr
}
// Delete explicitly deletes the gradient
func (lg *LinearGradient) Delete() { lg.grad.Delete() }
func (lg *LinearGradient) Delete() {
if lg.deleted {
return
}
lg.grad.Delete()
lg.grad = nil
lg.deleted = true
}
// Delete explicitly deletes the gradient
func (rg *RadialGradient) Delete() { rg.grad.Delete() }
func (rg *RadialGradient) Delete() {
if rg.deleted {
return
}
rg.grad.Delete()
rg.grad = nil
rg.deleted = true
}
func (lg *LinearGradient) load() {
if lg.loaded || len(lg.data) < 1 {
if lg.loaded || len(lg.data) < 1 || lg.deleted {
return
}
@ -88,7 +102,7 @@ func (lg *LinearGradient) load() {
}
func (rg *RadialGradient) load() {
if rg.loaded || len(rg.data) < 1 {
if rg.loaded || len(rg.data) < 1 || rg.deleted {
return
}

View file

@ -15,6 +15,7 @@ import (
type Image struct {
cv *Canvas
img backendbase.Image
deleted bool
}
// LoadImage loads an image. The src parameter can be either an image from the
@ -113,7 +114,11 @@ func (img *Image) Size() (int, int) { return img.img.Size() }
// Delete deletes the image from memory. Any draw calls with a deleted image
// will not do anything
func (img *Image) Delete() { img.img.Delete() }
func (img *Image) Delete() {
img.img.Delete()
img.img = nil
img.deleted = true
}
// Replace replaces the image with the new one
func (img *Image) Replace(src interface{}) error {
@ -137,20 +142,9 @@ func (img *Image) Replace(src interface{}) error {
// Where dx/dy/dw/dh are the destination coordinates and sx/sy/sw/sh are the
// source coordinates
func (cv *Canvas) DrawImage(image interface{}, coords ...float64) {
var img *Image
// var flip bool
// if cv2, ok := image.(*Canvas); ok && cv2.offscreen {
// img = &cv2.offscrImg
// flip = true
// } else {
img = cv.getImage(image)
// }
img := cv.getImage(image)
if img == nil {
return
}
if img.img.IsDeleted() {
if img == nil || img.deleted {
return
}
@ -169,11 +163,6 @@ func (cv *Canvas) DrawImage(image interface{}, coords ...float64) {
dw, dh = coords[6], coords[7]
}
// if flip {
// dy += dh
// dh = -dh
// }
var data [4][2]float64
data[0] = cv.tf(vec{dx, dy})
data[1] = cv.tf(vec{dx, dy + dh})