graphicscommand: Move the texel adjustment logic to graphicscommand package

This is a preparation for #879. The value of the texel adjustment
depends on the graphics driver (GLSL float precisions), and this
can be accessed only after the run loop runs. The place where
graphics commands are executed seems an appropriate place.

Updates #879
This commit is contained in:
Hajime Hoshi 2019-06-22 03:50:56 +09:00
parent f3cdb0537b
commit cddb93b9f6
3 changed files with 28 additions and 8 deletions

View File

@ -54,6 +54,11 @@ type command interface {
CanMerge(dst, src *Image, color *affine.ColorM, mode graphics.CompositeMode, filter graphics.Filter, address graphics.Address) bool
}
type size struct {
width float32
height float32
}
// commandQueue is a command queue for drawing commands.
type commandQueue struct {
// commands is a queue of drawing commands.
@ -70,6 +75,8 @@ type commandQueue struct {
// Rename or fix the program.
nvertices int
dstSizes []size
indices []uint16
nindices int
@ -83,12 +90,18 @@ type commandQueue struct {
var theCommandQueue = &commandQueue{}
// appendVertices appends vertices to the queue.
func (q *commandQueue) appendVertices(vertices []float32) {
func (q *commandQueue) appendVertices(vertices []float32, width, height float32) {
if len(q.vertices) < q.nvertices+len(vertices) {
n := q.nvertices + len(vertices) - len(q.vertices)
q.vertices = append(q.vertices, make([]float32, n)...)
q.dstSizes = append(q.dstSizes, make([]size, n/graphics.VertexFloatNum)...)
}
copy(q.vertices[q.nvertices:], vertices)
for i := 0; i < len(vertices)/graphics.VertexFloatNum; i++ {
idx := q.nvertices/graphics.VertexFloatNum + i
q.dstSizes[idx].width = width
q.dstSizes[idx].height = height
}
q.nvertices += len(vertices)
}
@ -140,9 +153,10 @@ func (q *commandQueue) EnqueueDrawTrianglesCommand(dst, src *Image, vertices []f
split = true
}
q.appendVertices(vertices)
n := len(vertices) / graphics.VertexFloatNum
q.appendVertices(vertices, float32(dst.width), float32(dst.height))
q.appendIndices(indices, uint16(q.nextIndex))
q.nextIndex += len(vertices) / graphics.VertexFloatNum
q.nextIndex += n
q.tmpNumIndices += len(indices)
// TODO: If dst is the screen, reorder the command to be the last.
@ -169,6 +183,15 @@ func (q *commandQueue) Flush() {
fmt.Println("--")
}
// Adjust texels.
// TODO: texelAdjustmentFactor can vary depends on the highp precisions (#879).
const texelAdjustmentFactor = 1.0 / 512.0
for i := 0; i < q.nvertices/graphics.VertexFloatNum; i++ {
s := q.dstSizes[i]
vs[i*graphics.VertexFloatNum+6] -= 1.0 / s.width * texelAdjustmentFactor
vs[i*graphics.VertexFloatNum+7] -= 1.0 / s.height * texelAdjustmentFactor
}
theGraphicsDriver.Begin()
for len(q.commands) > 0 {
nv := 0

View File

@ -49,7 +49,6 @@ type testVertexPutter struct {
func (t *testVertexPutter) PutVertex(vs []float32, dx, dy, sx, sy float32, bx0, by0, bx1, by1 float32, cr, cg, cb, ca float32) {
// The implementation is basically same as restorable.(*Image).PutVertex.
// This doesn't adjust texels, but this is fine as long as the rectangle is not rotated or scaled.
vs[0] = dx
vs[1] = dy
vs[2] = sx / t.w

View File

@ -240,8 +240,6 @@ func (i *Image) internalSize() (int, int) {
}
func (i *Image) PutVertex(vs []float32, dx, dy, sx, sy float32, bx0, by0, bx1, by1 float32, cr, cg, cb, ca float32) {
const texelAdjustmentFactor = 512.0
// Specifying a range explicitly here is redundant but this helps optimization
// to eliminate boundary checks.
//
@ -256,8 +254,8 @@ func (i *Image) PutVertex(vs []float32, dx, dy, sx, sy float32, bx0, by0, bx1, b
vs[3] = sy / float32(h)
vs[4] = bx0 / float32(w)
vs[5] = by0 / float32(h)
vs[6] = bx1/float32(w) - 1.0/float32(w)/texelAdjustmentFactor
vs[7] = by1/float32(h) - 1.0/float32(h)/texelAdjustmentFactor
vs[6] = bx1 / float32(w)
vs[7] = by1 / float32(h)
vs[8] = cr
vs[9] = cg
vs[10] = cb