Skip to content
This repository has been archived by the owner on Nov 5, 2022. It is now read-only.

Commit

Permalink
Rip out refCounted from the driver.
Browse files Browse the repository at this point in the history
Instead, use a mark-and-sweep per context.
Removes the horrible Release() interface method from Texture and Canvas.

GXUI seems a lot snappier, probably because we're not ref-twiddling
everything any more.

Fixes #111
  • Loading branch information
ben-clayton committed Aug 4, 2015
1 parent 1af203a commit 6069b27
Show file tree
Hide file tree
Showing 17 changed files with 106 additions and 204 deletions.
1 change: 0 additions & 1 deletion canvas.go
Expand Up @@ -23,5 +23,4 @@ type Canvas interface {
DrawPolygon(Polygon, Pen, Brush)
DrawRect(math.Rect, Brush)
DrawRoundedRect(rect math.Rect, tl, tr, bl, br float32, p Pen, b Brush)
Release()
}
2 changes: 0 additions & 2 deletions drivers/gl/blitter.go
Expand Up @@ -119,7 +119,6 @@ func newBlitter(ctx *context, stats *contextStats) *blitter {
}

func (b *blitter) destroy(ctx *context) {
b.quad.release()
b.copyShader.destroy(ctx)
b.colorShader.destroy(ctx)
b.fontShader.destroy(ctx)
Expand Down Expand Up @@ -297,7 +296,6 @@ func (b *blitter) commitGlyphs(ctx *context) {
"mSrc": mSrc,
})
gl.Enable(gl.SCISSOR_TEST)
s.release()
b.glyphBatch.GlyphPage = nil
b.glyphBatch.DstRects = b.glyphBatch.DstRects[:0]
b.glyphBatch.SrcRects = b.glyphBatch.SrcRects[:0]
Expand Down
47 changes: 0 additions & 47 deletions drivers/gl/canvas.go
Expand Up @@ -32,15 +32,8 @@ type drawState struct {
OriginPixels math.Point
}

type resource interface {
addRef()
release() bool
}

type canvas struct {
refCounted
sizeDips math.Size
resources []resource
ops []canvasOp
built bool
buildingPushCount int
Expand All @@ -53,13 +46,10 @@ func newCanvas(sizeDips math.Size) *canvas {
c := &canvas{
sizeDips: sizeDips,
}
c.init()
globalStats.canvasCount.inc()
return c
}

func (c *canvas) draw(ctx *context, dss *drawStateStack) {
c.assertAlive("draw")
ds := dss.head()
ctx.apply(ds)

Expand All @@ -69,31 +59,12 @@ func (c *canvas) draw(ctx *context, dss *drawStateStack) {
}

func (c *canvas) appendOp(name string, op canvasOp) {
c.assertAlive(name)
if c.built {
panic(fmt.Errorf("%s() called after Complete()", name))
}
c.ops = append(c.ops, op)
}

func (c *canvas) appendResource(r resource) {
r.addRef()
c.resources = append(c.resources, r)
}

func (c *canvas) release() bool {
if !c.refCounted.release() {
return false
}
for _, r := range c.resources {
r.release()
}
c.ops = nil
c.resources = nil
globalStats.canvasCount.dec()
return true
}

// gxui.Canvas compliance
func (c *canvas) Size() math.Size {
return c.sizeDips
Expand Down Expand Up @@ -164,7 +135,6 @@ func (c *canvas) DrawCanvas(cc gxui.Canvas, offsetDips math.Point) {
dss.pop()
ctx.apply(dss.head())
})
c.appendResource(childCanvas)
}

func (c *canvas) DrawRunes(f gxui.Font, r []rune, p []math.Point, col gxui.Color) {
Expand All @@ -186,10 +156,6 @@ func (c *canvas) DrawLines(lines gxui.Polygon, pen gxui.Pen) {
ctx.blitter.blitShape(ctx, *edge, pen.Color, ds)
}
})
if edge != nil {
c.appendResource(edge)
edge.release()
}
}

func (c *canvas) DrawPolygon(poly gxui.Polygon, pen gxui.Pen, brush gxui.Brush) {
Expand All @@ -203,14 +169,6 @@ func (c *canvas) DrawPolygon(poly gxui.Polygon, pen gxui.Pen, brush gxui.Brush)
ctx.blitter.blitShape(ctx, *edge, pen.Color, ds)
}
})
if fill != nil {
c.appendResource(fill)
fill.release()
}
if edge != nil {
c.appendResource(edge)
edge.release()
}
}

func (c *canvas) DrawRect(r math.Rect, brush gxui.Brush) {
Expand Down Expand Up @@ -242,9 +200,4 @@ func (c *canvas) DrawTexture(t gxui.Texture, r math.Rect) {
tc := ctx.getOrCreateTextureContext(t.(*texture))
ctx.blitter.blit(ctx, tc, tc.sizePixels.Rect(), ctx.resolution.rectDipsToPixels(r), dss.head())
})
c.appendResource(t.(*texture))
}

func (c *canvas) Release() {
c.release()
}
41 changes: 26 additions & 15 deletions drivers/gl/context.go
Expand Up @@ -10,6 +10,12 @@ import (
"github.com/goxjs/gl"
)

// contextResource is used as an anonymous field by types that are constructed
// per context.
type contextResource struct {
lastContextUse int // used for mark-and-sweeping the resource.
}

type context struct {
blitter *blitter
resolution resolution
Expand All @@ -19,6 +25,7 @@ type context struct {
indexBufferContexts map[*indexBuffer]*indexBufferContext
sizeDips, sizePixels math.Size
clip math.Rect
frame int
}

func newContext() *context {
Expand Down Expand Up @@ -52,42 +59,43 @@ func (c *context) destroy() {
}

func (c *context) beginDraw(sizeDips, sizePixels math.Size) {
// Reap any dead textures
dipsToPixels := float32(sizePixels.W) / float32(sizeDips.W)

c.sizeDips = sizeDips
c.sizePixels = sizePixels
c.resolution = resolution(dipsToPixels*65536 + 0.5)

c.stats.drawCallCount = 0
c.stats.timer("Frame").start()
}

func (c *context) endDraw() {
// Reap any unused resources
for texture, tc := range c.textureContexts {
if !texture.alive() {
if tc.lastContextUse != c.frame {
delete(c.textureContexts, texture)
tc.destroy()
c.stats.textureCount--
}
}
for stream, sc := range c.vertexStreamContexts {
if !stream.alive() {
if sc.lastContextUse != c.frame {
delete(c.vertexStreamContexts, stream)
sc.destroy()
c.stats.vertexStreamCount--
}
}
for buffer, ic := range c.indexBufferContexts {
if !buffer.alive() {
if ic.lastContextUse != c.frame {
delete(c.indexBufferContexts, buffer)
ic.destroy()
c.stats.indexBufferCount--
}
}

dipsToPixels := float32(sizePixels.W) / float32(sizeDips.W)

c.sizeDips = sizeDips
c.sizePixels = sizePixels
c.resolution = resolution(dipsToPixels*65536 + 0.5)

c.stats.drawCallCount = 0
c.stats.timer("Frame").start()
}

func (c *context) endDraw() {
c.stats.timer("Frame").stop()
c.stats.frameCount++
c.frame++
}

func (c *context) getOrCreateTextureContext(t *texture) *textureContext {
Expand All @@ -97,6 +105,7 @@ func (c *context) getOrCreateTextureContext(t *texture) *textureContext {
c.textureContexts[t] = tc
c.stats.textureCount++
}
tc.lastContextUse = c.frame
return tc
}

Expand All @@ -107,6 +116,7 @@ func (c *context) getOrCreateVertexStreamContext(vs *vertexStream) *vertexStream
c.vertexStreamContexts[vs] = vc
c.stats.vertexStreamCount++
}
vc.lastContextUse = c.frame
return vc
}

Expand All @@ -117,6 +127,7 @@ func (c *context) getOrCreateIndexBufferContext(ib *indexBuffer) *indexBufferCon
c.indexBufferContexts[ib] = ic
c.stats.indexBufferCount++
}
ic.lastContextUse = c.frame
return ic
}

Expand Down
9 changes: 3 additions & 6 deletions drivers/gl/glyph_page.go
Expand Up @@ -5,11 +5,12 @@
package gl

import (
"github.com/google/gxui/math"
"image"
"image/png"
"os"

"github.com/google/gxui/math"

"code.google.com/p/freetype-go/freetype/raster"
"code.google.com/p/freetype-go/freetype/truetype"
)
Expand Down Expand Up @@ -158,11 +159,7 @@ func (p *glyphPage) add(rune rune, g *glyph) bool {
if h > p.rowHeight {
p.rowHeight = h
}

if p.tex != nil {
p.tex.Release()
p.tex = nil
}
p.tex = nil

return true
}
Expand Down
26 changes: 9 additions & 17 deletions drivers/gl/index_buffer.go
Expand Up @@ -12,17 +12,10 @@ import (
)

type indexBuffer struct {
refCounted
data []byte
ty primitiveType
}

type indexBufferContext struct {
buffer gl.Buffer
ty primitiveType
length int
}

func newIndexBuffer(ty primitiveType, data16 []uint16) *indexBuffer {
switch ty {
case ptUbyte, ptUshort, ptUint:
Expand All @@ -44,19 +37,9 @@ func newIndexBuffer(ty primitiveType, data16 []uint16) *indexBuffer {
data: data,
ty: ty,
}
ib.init()
globalStats.indexBufferCount.inc()
return ib
}

func (b *indexBuffer) release() bool {
if !b.refCounted.release() {
return false
}
globalStats.indexBufferCount.dec()
return true
}

func (b *indexBuffer) newContext() *indexBufferContext {
dataVal := reflect.ValueOf(b.data)
length := dataVal.Len() / 2 // HACK: Hardcode support for only ptUshort.
Expand All @@ -67,14 +50,23 @@ func (b *indexBuffer) newContext() *indexBufferContext {
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Buffer{})
checkError()

globalStats.indexBufferContextCount.inc()
return &indexBufferContext{
buffer: buffer,
ty: b.ty,
length: length,
}
}

type indexBufferContext struct {
contextResource
buffer gl.Buffer
ty primitiveType
length int
}

func (c *indexBufferContext) destroy() {
globalStats.indexBufferContextCount.dec()
gl.DeleteBuffer(c.buffer)
c.buffer = gl.Buffer{}
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/gl/refcounted.go
Expand Up @@ -4,6 +4,7 @@

package gl

/*
import (
"fmt"
"runtime"
Expand Down Expand Up @@ -72,3 +73,4 @@ func (r *refCounted) assertAlive(funcName string) {
}
}
}
*/
21 changes: 0 additions & 21 deletions drivers/gl/shape.go
Expand Up @@ -7,7 +7,6 @@ package gl
import "github.com/goxjs/gl"

type shape struct {
refCounted
vb *vertexBuffer
ib *indexBuffer
drawMode drawMode
Expand All @@ -23,27 +22,9 @@ func newShape(vb *vertexBuffer, ib *indexBuffer, drawMode drawMode) *shape {
ib: ib,
drawMode: drawMode,
}
s.init()
globalStats.shapeCount.inc()
return s
}

func (s *shape) release() bool {
if !s.refCounted.release() {
return false
}
if s.vb != nil {
s.vb.release()
s.vb = nil
}
if s.ib != nil {
s.ib.release()
s.ib = nil
}
globalStats.shapeCount.dec()
return true
}

func newQuadShape() *shape {
pos := newVertexStream("aPosition", stFloatVec2, []float32{
0.0, 0.0,
Expand All @@ -60,8 +41,6 @@ func newQuadShape() *shape {
}

func (s shape) draw(ctx *context, shader *shaderProgram, ub uniformBindings) {
s.assertAlive("draw")

shader.bind(ctx, s.vb, ub)
if s.ib != nil {
ctx.getOrCreateIndexBufferContext(s.ib).render(s.drawMode)
Expand Down

0 comments on commit 6069b27

Please sign in to comment.