internal/graphicsdriver: reland: add FillRule and replace boolean values with this

Updates #2782
This commit is contained in:
Hajime Hoshi 2023-11-04 18:09:47 +09:00
parent f695df5924
commit 4e93efa5ac
20 changed files with 178 additions and 155 deletions

View File

@ -262,7 +262,7 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) {
})
}
i.image.DrawTriangles(srcs, vs, is, blend, i.adjustedBounds(), [graphics.ShaderImageCount]image.Rectangle{img.adjustedBounds()}, shader.shader, i.tmpUniforms, false, canSkipMipmap(geoM, filter), false)
i.image.DrawTriangles(srcs, vs, is, blend, i.adjustedBounds(), [graphics.ShaderImageCount]image.Rectangle{img.adjustedBounds()}, shader.shader, i.tmpUniforms, graphicsdriver.FillAll, canSkipMipmap(geoM, filter), false)
}
// Vertex represents a vertex passed to DrawTriangles.
@ -312,11 +312,11 @@ type FillRule int
const (
// FillAll indicates all the triangles are rendered regardless of overlaps.
FillAll FillRule = iota
FillAll FillRule = FillRule(graphicsdriver.FillAll)
// EvenOdd means that triangles are rendered based on the even-odd rule.
// If and only if the number of overlaps is odd, the region is rendered.
EvenOdd
EvenOdd FillRule = FillRule(graphicsdriver.EvenOdd)
)
// ColorScaleMode is the mode of color scales in vertices.
@ -511,7 +511,7 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o
})
}
i.image.DrawTriangles(srcs, vs, is, blend, i.adjustedBounds(), [graphics.ShaderImageCount]image.Rectangle{img.adjustedBounds()}, shader.shader, i.tmpUniforms, options.FillRule == EvenOdd, filter != builtinshader.FilterLinear, options.AntiAlias)
i.image.DrawTriangles(srcs, vs, is, blend, i.adjustedBounds(), [graphics.ShaderImageCount]image.Rectangle{img.adjustedBounds()}, shader.shader, i.tmpUniforms, graphicsdriver.FillRule(options.FillRule), filter != builtinshader.FilterLinear, options.AntiAlias)
}
// DrawTrianglesShaderOptions represents options for DrawTrianglesShader.
@ -676,7 +676,7 @@ func (i *Image) DrawTrianglesShader(vertices []Vertex, indices []uint16, shader
i.tmpUniforms = i.tmpUniforms[:0]
i.tmpUniforms = shader.appendUniforms(i.tmpUniforms, options.Uniforms)
i.image.DrawTriangles(imgs, vs, is, blend, i.adjustedBounds(), srcRegions, shader.shader, i.tmpUniforms, options.FillRule == EvenOdd, true, options.AntiAlias)
i.image.DrawTriangles(imgs, vs, is, blend, i.adjustedBounds(), srcRegions, shader.shader, i.tmpUniforms, graphicsdriver.FillRule(options.FillRule), true, options.AntiAlias)
}
// DrawRectShaderOptions represents options for DrawRectShader.
@ -806,7 +806,7 @@ func (i *Image) DrawRectShader(width, height int, shader *Shader, options *DrawR
i.tmpUniforms = i.tmpUniforms[:0]
i.tmpUniforms = shader.appendUniforms(i.tmpUniforms, options.Uniforms)
i.image.DrawTriangles(imgs, vs, is, blend, i.adjustedBounds(), srcRegions, shader.shader, i.tmpUniforms, false, true, false)
i.image.DrawTriangles(imgs, vs, is, blend, i.adjustedBounds(), srcRegions, shader.shader, i.tmpUniforms, graphicsdriver.FillAll, true, false)
}
// SubImage returns an image representing the portion of the image p visible through r.

View File

@ -251,7 +251,7 @@ func (i *Image) ensureIsolatedFromSource(backends []*backend) {
is := graphics.QuadIndices()
dr := image.Rect(0, 0, i.width, i.height)
newI.drawTriangles([graphics.ShaderImageCount]*Image{i}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader, nil, false)
newI.drawTriangles([graphics.ShaderImageCount]*Image{i}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader, nil, graphicsdriver.FillAll)
newI.moveTo(i)
}
@ -281,7 +281,7 @@ func (i *Image) putOnSourceBackend(graphicsDriver graphicsdriver.Graphics) {
graphics.QuadVertices(vs, 0, 0, w, h, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, i.width, i.height)
newI.drawTriangles([graphics.ShaderImageCount]*Image{i}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader, nil, false)
newI.drawTriangles([graphics.ShaderImageCount]*Image{i}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader, nil, graphicsdriver.FillAll)
newI.moveTo(i)
i.usedAsSourceCount = 0
@ -313,7 +313,7 @@ func (i *Image) regionWithPadding() image.Rectangle {
// 5: Color G
// 6: Color B
// 7: Color Y
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, evenOdd bool) {
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) {
backendsM.Lock()
defer backendsM.Unlock()
@ -326,15 +326,15 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices [
copy(us, uniforms)
appendDeferred(func() {
i.drawTriangles(srcs, vs, is, blend, dstRegion, srcRegions, shader, us, evenOdd)
i.drawTriangles(srcs, vs, is, blend, dstRegion, srcRegions, shader, us, fillRule)
})
return
}
i.drawTriangles(srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, evenOdd)
i.drawTriangles(srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule)
}
func (i *Image) drawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, evenOdd bool) {
func (i *Image) drawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) {
backends := make([]*backend, 0, len(srcs))
for _, src := range srcs {
if src == nil {
@ -415,7 +415,7 @@ func (i *Image) drawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices [
imgs[i] = src.backend.restorable
}
i.backend.restorable.DrawTriangles(imgs, vertices, indices, blend, dstRegion, srcRegions, shader.ensureShader(), uniforms, evenOdd)
i.backend.restorable.DrawTriangles(imgs, vertices, indices, blend, dstRegion, srcRegions, shader.ensureShader(), uniforms, fillRule)
for _, src := range srcs {
if src == nil {

View File

@ -103,7 +103,7 @@ func TestEnsureIsolatedFromSourceBackend(t *testing.T) {
vs := quadVertices(size/2, size/2, size/4, size/4, 1)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, size, size)
img4.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img3}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
img4.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img3}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img4.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -111,7 +111,7 @@ func TestEnsureIsolatedFromSourceBackend(t *testing.T) {
// img5 is not allocated now, but is allocated at DrawTriangles.
vs = quadVertices(0, 0, size/2, size/2, 1)
dr = image.Rect(0, 0, size/2, size/2)
img3.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img5}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
img3.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img5}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img3.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -141,7 +141,7 @@ func TestEnsureIsolatedFromSourceBackend(t *testing.T) {
// Check further drawing doesn't cause panic.
// This bug was fixed by 03dcd948.
vs = quadVertices(0, 0, size/2, size/2, 1)
img4.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img3}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
img4.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img3}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
}
func TestReputOnSourceBackend(t *testing.T) {
@ -185,7 +185,7 @@ func TestReputOnSourceBackend(t *testing.T) {
// Render onto img1. The count should not matter.
for i := 0; i < 5; i++ {
vs := quadVertices(size, size, 0, 0, 1)
img1.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img2}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
img1.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img2}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img1.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -197,7 +197,7 @@ func TestReputOnSourceBackend(t *testing.T) {
for i := 0; i < atlas.BaseCountToPutOnSourceBackend*2; i++ {
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
vs := quadVertices(size, size, 0, 0, 1)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img1.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -205,7 +205,7 @@ func TestReputOnSourceBackend(t *testing.T) {
// Finally, img1 is on a source backend.
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
vs := quadVertices(size, size, 0, 0, 1)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img1.IsOnSourceBackendForTesting(), true; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -230,7 +230,7 @@ func TestReputOnSourceBackend(t *testing.T) {
}
vs = quadVertices(size, size, 0, 0, 1)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img1.IsOnSourceBackendForTesting(), true; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -256,7 +256,7 @@ func TestReputOnSourceBackend(t *testing.T) {
// Use img1 as a render target again. The count should not matter.
for i := 0; i < 5; i++ {
vs := quadVertices(size, size, 0, 0, 1)
img1.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img2}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
img1.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img2}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img1.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -268,7 +268,7 @@ func TestReputOnSourceBackend(t *testing.T) {
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
img1.WritePixels(make([]byte, 4*size*size), image.Rect(0, 0, size, size))
vs := quadVertices(size, size, 0, 0, 1)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img1.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -277,7 +277,7 @@ func TestReputOnSourceBackend(t *testing.T) {
// img1 is not on an atlas due to WritePixels.
vs = quadVertices(size, size, 0, 0, 1)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img1.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -286,7 +286,7 @@ func TestReputOnSourceBackend(t *testing.T) {
for i := 0; i < atlas.BaseCountToPutOnSourceBackend*2; i++ {
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
vs := quadVertices(size, size, 0, 0, 1)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img3}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
img0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{img3}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := img3.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -381,7 +381,7 @@ func TestWritePixelsAfterDrawTriangles(t *testing.T) {
vs := quadVertices(w, h, 0, 0, 1)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
dst.WritePixels(pix, image.Rect(0, 0, w, h))
pix = make([]byte, 4*w*h)
@ -424,7 +424,7 @@ func TestSmallImages(t *testing.T) {
vs := quadVertices(w, h, 0, 0, 1)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
pix = make([]byte, 4*w*h)
if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil {
@ -467,7 +467,7 @@ func TestLongImages(t *testing.T) {
vs := quadVertices(w, h, 0, 0, scale)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, dstW, dstH)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
pix = make([]byte, 4*dstW*dstH)
if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, dstW, dstH)); err != nil {
@ -579,7 +579,7 @@ func TestDeallocatedAndReputOnSourceBackend(t *testing.T) {
vs := quadVertices(size, size, 0, 0, 1)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, size, size)
src.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src2}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
src.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src2}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := src.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -588,7 +588,7 @@ func TestDeallocatedAndReputOnSourceBackend(t *testing.T) {
for i := 0; i < atlas.BaseCountToPutOnSourceBackend/2; i++ {
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
vs := quadVertices(size, size, 0, 0, 1)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := src.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -622,7 +622,7 @@ func TestImageIsNotReputOnSourceBackendWithoutUsingAsSource(t *testing.T) {
// Call DrawTriangles multiple times.
// The number of DrawTriangles doesn't matter as long as these are called in one frame.
for i := 0; i < 2; i++ {
src2.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
src2.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
}
if got, want := src2.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
@ -641,7 +641,7 @@ func TestImageIsNotReputOnSourceBackendWithoutUsingAsSource(t *testing.T) {
for i := 0; i < atlas.BaseCountToPutOnSourceBackend; i++ {
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
vs := quadVertices(size, size, 0, 0, 1)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src2}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src2}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
if got, want := src2.IsOnSourceBackendForTesting(), false; got != want {
t.Errorf("got: %v, want: %v", got, want)
}
@ -763,14 +763,14 @@ func TestDestinationCountOverflow(t *testing.T) {
// Use dst0 as a destination for a while.
for i := 0; i < 31; i++ {
dst0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
dst0.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
}
// Use dst0 as a source for a while.
// As dst0 is used as a destination too many times (31 is a maximum), dst0's backend should never be a source backend.
for i := 0; i < 100; i++ {
dst1.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{dst0}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
dst1.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{dst0}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
if dst0.IsOnSourceBackendForTesting() {
t.Errorf("dst0 cannot be on a source backend: %d", i)
@ -796,7 +796,7 @@ func TestIteratingImagesToPutOnSourceBackend(t *testing.T) {
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
for _, img := range srcs {
img.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
img.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
}
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
@ -804,7 +804,7 @@ func TestIteratingImagesToPutOnSourceBackend(t *testing.T) {
// Check iterating the registered image works correctly.
for i := 0; i < 100; i++ {
for _, src := range srcs {
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
}
atlas.PutImagesOnSourceBackendForTesting(ui.Get().GraphicsDriverForTesting())
}

View File

@ -36,12 +36,12 @@ func TestShaderFillTwice(t *testing.T) {
dr := image.Rect(0, 0, w, h)
g := ui.Get().GraphicsDriverForTesting()
s0 := atlas.NewShader(etesting.ShaderProgramFill(0xff, 0xff, 0xff, 0xff))
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s0, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s0, nil, graphicsdriver.FillAll)
// Vertices must be recreated (#1755)
vs = quadVertices(w, h, 0, 0, 1)
s1 := atlas.NewShader(etesting.ShaderProgramFill(0x80, 0x80, 0x80, 0xff))
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s1, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s1, nil, graphicsdriver.FillAll)
pix := make([]byte, 4*w*h)
if err := dst.ReadPixels(g, pix, image.Rect(0, 0, w, h)); err != nil {
@ -64,11 +64,11 @@ func TestImageDrawTwice(t *testing.T) {
vs := quadVertices(w, h, 0, 0, 1)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src0}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src0}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
// Vertices must be recreated (#1755)
vs = quadVertices(w, h, 0, 0, 1)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src1}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, atlas.NearestFilterShader, nil, graphicsdriver.FillAll)
pix := make([]byte, 4*w*h)
if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil {

View File

@ -92,7 +92,7 @@ func (i *Image) WritePixels(pix []byte, region image.Rectangle) {
// DrawTriangles draws the src image with the given vertices.
//
// Copying vertices and indices is the caller's responsibility.
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *atlas.Shader, uniforms []uint32, evenOdd bool) {
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *atlas.Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) {
for _, src := range srcs {
if i == src {
panic("buffered: Image.DrawTriangles: source images must be different from the receiver")
@ -108,5 +108,5 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices [
imgs[i] = img.img
}
i.img.DrawTriangles(imgs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, evenOdd)
i.img.DrawTriangles(imgs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule)
}

View File

@ -68,7 +68,7 @@ type drawTrianglesCommand struct {
dstRegions []graphicsdriver.DstRegion
shader *Shader
uniforms []uint32
evenOdd bool
fillRule graphicsdriver.FillRule
}
func (c *drawTrianglesCommand) String() string {
@ -98,7 +98,7 @@ func (c *drawTrianglesCommand) String() string {
}
}
return fmt.Sprintf("draw-triangles: dst: %s <- src: [%s], num of dst regions: %d, num of indices: %d, blend: %s, even-odd: %t", dst, strings.Join(srcstrs[:], ", "), len(c.dstRegions), c.numIndices(), blend, c.evenOdd)
return fmt.Sprintf("draw-triangles: dst: %s <- src: [%s], num of dst regions: %d, num of indices: %d, blend: %s, fill rule: %s", dst, strings.Join(srcstrs[:], ", "), len(c.dstRegions), c.numIndices(), blend, c.fillRule)
}
// Exec executes the drawTrianglesCommand.
@ -117,7 +117,7 @@ func (c *drawTrianglesCommand) Exec(commandQueue *commandQueue, graphicsDriver g
imgs[i] = src.image.ID()
}
return graphicsDriver.DrawTriangles(c.dst.image.ID(), imgs, c.shader.shader.ID(), c.dstRegions, indexOffset, c.blend, c.uniforms, c.evenOdd)
return graphicsDriver.DrawTriangles(c.dst.image.ID(), imgs, c.shader.shader.ID(), c.dstRegions, indexOffset, c.blend, c.uniforms, c.fillRule)
}
func (c *drawTrianglesCommand) NeedsSync() bool {
@ -142,7 +142,7 @@ func (c *drawTrianglesCommand) setVertices(vertices []float32) {
// CanMergeWithDrawTrianglesCommand returns a boolean value indicating whether the other drawTrianglesCommand can be merged
// with the drawTrianglesCommand c.
func (c *drawTrianglesCommand) CanMergeWithDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderImageCount]*Image, vertices []float32, blend graphicsdriver.Blend, shader *Shader, uniforms []uint32, evenOdd bool) bool {
func (c *drawTrianglesCommand) CanMergeWithDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderImageCount]*Image, vertices []float32, blend graphicsdriver.Blend, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) bool {
if c.shader != shader {
return false
}
@ -163,10 +163,10 @@ func (c *drawTrianglesCommand) CanMergeWithDrawTrianglesCommand(dst *Image, srcs
if c.blend != blend {
return false
}
if c.evenOdd != evenOdd {
if c.fillRule != fillRule {
return false
}
if c.evenOdd && mightOverlapDstRegions(c.vertices, vertices) {
if c.fillRule == graphicsdriver.EvenOdd && mightOverlapDstRegions(c.vertices, vertices) {
return false
}
return true

View File

@ -101,7 +101,7 @@ func mustUseDifferentVertexBuffer(nextNumVertexFloats int) bool {
}
// EnqueueDrawTrianglesCommand enqueues a drawing-image command.
func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, evenOdd bool) {
func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) {
if len(vertices) > maxVertexFloatCount {
panic(fmt.Sprintf("graphicscommand: len(vertices) must equal to or less than %d but was %d", maxVertexFloatCount, len(vertices)))
}
@ -129,7 +129,7 @@ func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.Sh
// TODO: If dst is the screen, reorder the command to be the last.
if !split && 0 < len(q.commands) {
if last, ok := q.commands[len(q.commands)-1].(*drawTrianglesCommand); ok {
if last.CanMergeWithDrawTrianglesCommand(dst, srcs, vertices, blend, shader, uniforms, evenOdd) {
if last.CanMergeWithDrawTrianglesCommand(dst, srcs, vertices, blend, shader, uniforms, fillRule) {
last.setVertices(q.lastVertices(len(vertices) + last.numVertices()))
if last.dstRegions[len(last.dstRegions)-1].Region == dstRegion {
last.dstRegions[len(last.dstRegions)-1].IndexCount += len(indices)
@ -157,7 +157,7 @@ func (q *commandQueue) EnqueueDrawTrianglesCommand(dst *Image, srcs [graphics.Sh
}
c.shader = shader
c.uniforms = uniforms
c.evenOdd = evenOdd
c.fillRule = fillRule
q.commands = append(q.commands, c)
}
@ -493,11 +493,11 @@ func (c *commandQueueManager) putCommandQueue(commandQueue *commandQueue) {
c.pool.put(commandQueue)
}
func (c *commandQueueManager) enqueueDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, evenOdd bool) {
func (c *commandQueueManager) enqueueDrawTrianglesCommand(dst *Image, srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) {
if c.current == nil {
c.current, _ = c.pool.get()
}
c.current.EnqueueDrawTrianglesCommand(dst, srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, evenOdd)
c.current.EnqueueDrawTrianglesCommand(dst, srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule)
}
func (c *commandQueueManager) flush(graphicsDriver graphicsdriver.Graphics, endFrame bool, swapBuffersForGL func()) error {

View File

@ -130,7 +130,7 @@ func (i *Image) InternalSize() (int, int) {
//
// If the source image is not specified, i.e., src is nil and there is no image in the uniform variables, the
// elements for the source image are not used.
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, evenOdd bool) {
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) {
for _, src := range srcs {
if src == nil {
continue
@ -142,7 +142,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices [
}
i.flushBufferedWritePixels()
theCommandQueueManager.enqueueDrawTrianglesCommand(i, srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, evenOdd)
theCommandQueueManager.enqueueDrawTrianglesCommand(i, srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule)
}
// ReadPixels reads the image's pixels.

View File

@ -59,7 +59,7 @@ func TestClear(t *testing.T) {
vs := quadVertices(w/2, h/2)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{src}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderImageCount]image.Rectangle{}, nearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{src}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderImageCount]image.Rectangle{}, nearestFilterShader, nil, graphicsdriver.FillAll)
pix := make([]byte, 4*w*h)
if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), []graphicsdriver.PixelsArgs{
@ -90,8 +90,8 @@ func TestWritePixelsPartAfterDrawTriangles(t *testing.T) {
vs := quadVertices(w/2, h/2)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{clr}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderImageCount]image.Rectangle{}, nearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, nearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{clr}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderImageCount]image.Rectangle{}, nearestFilterShader, nil, graphicsdriver.FillAll)
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, nearestFilterShader, nil, graphicsdriver.FillAll)
bs := graphics.NewManagedBytes(4, func(bs []byte) {
for i := range bs {
bs[i] = 0
@ -109,11 +109,11 @@ func TestShader(t *testing.T) {
vs := quadVertices(w, h)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{clr}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderImageCount]image.Rectangle{}, nearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{clr}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderImageCount]image.Rectangle{}, nearestFilterShader, nil, graphicsdriver.FillAll)
g := ui.Get().GraphicsDriverForTesting()
s := graphicscommand.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff))
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillAll)
pix := make([]byte, 4*w*h)
if err := dst.ReadPixels(g, []graphicsdriver.PixelsArgs{

View File

@ -519,7 +519,7 @@ func (g *graphics11) removeShader(s *shader11) {
delete(g.shaders, s.id)
}
func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, evenOdd bool) error {
func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
// Remove bound textures first. This is needed to avoid warnings on the debugger.
g.deviceContext.OMSetRenderTargets([]*_ID3D11RenderTargetView{nil}, nil)
srvs := [graphics.ShaderImageCount]*_ID3D11ShaderResourceView{}
@ -547,7 +547,7 @@ func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphic
},
})
if err := dst.setAsRenderTarget(evenOdd); err != nil {
if err := dst.setAsRenderTarget(fillRule != graphicsdriver.FillAll); err != nil {
return err
}
@ -557,7 +557,7 @@ func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphic
return err
}
if !evenOdd {
if fillRule == graphicsdriver.FillAll {
bs, err := g.blendState(blend, noStencil)
if err != nil {
return err
@ -581,7 +581,10 @@ func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphic
},
})
if evenOdd {
switch fillRule {
case graphicsdriver.FillAll:
g.deviceContext.DrawIndexed(uint32(dstRegion.IndexCount), uint32(indexOffset), 0)
case graphicsdriver.EvenOdd:
bs, err := g.blendState(blend, prepareStencil)
if err != nil {
return err
@ -605,8 +608,6 @@ func (g *graphics11) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphic
}
g.deviceContext.OMSetDepthStencilState(dss, 0)
g.deviceContext.DrawIndexed(uint32(dstRegion.IndexCount), uint32(indexOffset), 0)
} else {
g.deviceContext.DrawIndexed(uint32(dstRegion.IndexCount), uint32(indexOffset), 0)
}
indexOffset += dstRegion.IndexCount

View File

@ -1086,7 +1086,7 @@ func (g *graphics12) NewShader(program *shaderir.Program) (graphicsdriver.Shader
return s, nil
}
func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, evenOdd bool) error {
func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
if shaderID == graphicsdriver.InvalidShaderID {
return fmt.Errorf("directx: shader ID is invalid")
}
@ -1097,7 +1097,7 @@ func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.
// Release constant buffers when too many ones will be created.
numPipelines := 1
if evenOdd {
if fillRule == graphicsdriver.EvenOdd {
numPipelines = 2
}
if len(g.pipelineStates.constantBuffers[g.frameIndex])+numPipelines > numDescriptorsPerFrame {
@ -1129,7 +1129,7 @@ func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.
g.drawCommandList.ResourceBarrier(resourceBarriers)
}
if err := dst.setAsRenderTarget(g.drawCommandList, g.device, evenOdd); err != nil {
if err := dst.setAsRenderTarget(g.drawCommandList, g.device, fillRule != graphicsdriver.FillAll); err != nil {
return err
}
@ -1162,7 +1162,7 @@ func (g *graphics12) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.
Format: _DXGI_FORMAT_R32_UINT,
})
if err := g.pipelineStates.drawTriangles(g.device, g.drawCommandList, g.frameIndex, dst.screen, srcImages, shader, dstRegions, adjustedUniforms, blend, indexOffset, evenOdd); err != nil {
if err := g.pipelineStates.drawTriangles(g.device, g.drawCommandList, g.frameIndex, dst.screen, srcImages, shader, dstRegions, adjustedUniforms, blend, indexOffset, fillRule); err != nil {
return err
}

View File

@ -180,7 +180,7 @@ func (p *pipelineStates) initialize(device *_ID3D12Device) (ferr error) {
return nil
}
func (p *pipelineStates) drawTriangles(device *_ID3D12Device, commandList *_ID3D12GraphicsCommandList, frameIndex int, screen bool, srcs [graphics.ShaderImageCount]*image12, shader *shader12, dstRegions []graphicsdriver.DstRegion, uniforms []uint32, blend graphicsdriver.Blend, indexOffset int, evenOdd bool) error {
func (p *pipelineStates) drawTriangles(device *_ID3D12Device, commandList *_ID3D12GraphicsCommandList, frameIndex int, screen bool, srcs [graphics.ShaderImageCount]*image12, shader *shader12, dstRegions []graphicsdriver.DstRegion, uniforms []uint32, blend graphicsdriver.Blend, indexOffset int, fillRule graphicsdriver.FillRule) error {
idx := len(p.constantBuffers[frameIndex])
if idx >= numDescriptorsPerFrame {
return fmt.Errorf("directx: too many constant buffers")
@ -289,7 +289,7 @@ func (p *pipelineStates) drawTriangles(device *_ID3D12Device, commandList *_ID3D
}
commandList.SetGraphicsRootDescriptorTable(2, sh)
if !evenOdd {
if fillRule == graphicsdriver.FillAll {
s, err := shader.pipelineState(blend, noStencil, screen)
if err != nil {
return err
@ -306,7 +306,10 @@ func (p *pipelineStates) drawTriangles(device *_ID3D12Device, commandList *_ID3D
bottom: int32(dstRegion.Region.Max.Y),
},
})
if evenOdd {
switch fillRule {
case graphicsdriver.FillAll:
commandList.DrawIndexedInstanced(uint32(dstRegion.IndexCount), 1, uint32(indexOffset), 0, 0)
case graphicsdriver.EvenOdd:
s, err := shader.pipelineState(blend, prepareStencil, screen)
if err != nil {
return err
@ -320,8 +323,6 @@ func (p *pipelineStates) drawTriangles(device *_ID3D12Device, commandList *_ID3D
}
commandList.SetPipelineState(s)
commandList.DrawIndexedInstanced(uint32(dstRegion.IndexCount), 1, uint32(indexOffset), 0, 0)
} else {
commandList.DrawIndexedInstanced(uint32(dstRegion.IndexCount), 1, uint32(indexOffset), 0, 0)
}
indexOffset += dstRegion.IndexCount
}

View File

@ -15,6 +15,7 @@
package graphicsdriver
import (
"fmt"
"image"
"github.com/hajimehoshi/ebiten/v2/internal/graphics"
@ -26,6 +27,24 @@ type DstRegion struct {
IndexCount int
}
type FillRule int
const (
FillAll FillRule = iota
EvenOdd
)
func (f FillRule) String() string {
switch f {
case FillAll:
return "FillAll"
case EvenOdd:
return "EvenOdd"
default:
return fmt.Sprintf("FillRule(%d)", f)
}
}
const (
InvalidImageID = 0
InvalidShaderID = 0
@ -47,7 +66,7 @@ type Graphics interface {
NewShader(program *shaderir.Program) (Shader, error)
// DrawTriangles draws an image onto another image with the given parameters.
DrawTriangles(dst ImageID, srcs [graphics.ShaderImageCount]ImageID, shader ShaderID, dstRegions []DstRegion, indexOffset int, blend Blend, uniforms []uint32, evenOdd bool) error
DrawTriangles(dst ImageID, srcs [graphics.ShaderImageCount]ImageID, shader ShaderID, dstRegions []DstRegion, indexOffset int, blend Blend, uniforms []uint32, fillRule FillRule) error
}
type Resetter interface {

View File

@ -47,7 +47,7 @@ type Graphics struct {
unusedBuffers map[mtl.Buffer]struct{}
lastDst *Image
lastEvenOdd bool
lastFillRule graphicsdriver.FillRule
vb mtl.Buffer
ib mtl.Buffer
@ -468,15 +468,15 @@ func (g *Graphics) flushRenderCommandEncoderIfNeeded() {
g.lastDst = nil
}
func (g *Graphics) draw(dst *Image, dstRegions []graphicsdriver.DstRegion, srcs [graphics.ShaderImageCount]*Image, indexOffset int, shader *Shader, uniforms [][]uint32, blend graphicsdriver.Blend, evenOdd bool) error {
func (g *Graphics) draw(dst *Image, dstRegions []graphicsdriver.DstRegion, srcs [graphics.ShaderImageCount]*Image, indexOffset int, shader *Shader, uniforms [][]uint32, blend graphicsdriver.Blend, fillRule graphicsdriver.FillRule) error {
// When preparing a stencil buffer, flush the current render command encoder
// to make sure the stencil buffer is cleared when loading.
// TODO: What about clearing the stencil buffer by vertices?
if g.lastDst != dst || g.lastEvenOdd != evenOdd || evenOdd {
if g.lastDst != dst || g.lastFillRule != fillRule || fillRule == graphicsdriver.EvenOdd {
g.flushRenderCommandEncoderIfNeeded()
}
g.lastDst = dst
g.lastEvenOdd = evenOdd
g.lastFillRule = fillRule
if g.rce == (mtl.RenderCommandEncoder{}) {
rpd := mtl.RenderPassDescriptor{}
@ -498,7 +498,7 @@ func (g *Graphics) draw(dst *Image, dstRegions []graphicsdriver.DstRegion, srcs
rpd.ColorAttachments[0].Texture = t
rpd.ColorAttachments[0].ClearColor = mtl.ClearColor{}
if evenOdd {
if fillRule == graphicsdriver.EvenOdd {
dst.ensureStencil()
rpd.StencilAttachment.LoadAction = mtl.LoadActionClear
rpd.StencilAttachment.StoreAction = mtl.StoreActionDontCare
@ -543,7 +543,14 @@ func (g *Graphics) draw(dst *Image, dstRegions []graphicsdriver.DstRegion, srcs
drawWithStencilRpss mtl.RenderPipelineState
noStencilRpss mtl.RenderPipelineState
)
if evenOdd {
switch fillRule {
case graphicsdriver.FillAll:
s, err := shader.RenderPipelineState(&g.view, blend, noStencil, dst.screen)
if err != nil {
return err
}
noStencilRpss = s
case graphicsdriver.EvenOdd:
s, err := shader.RenderPipelineState(&g.view, blend, prepareStencil, dst.screen)
if err != nil {
return err
@ -555,12 +562,6 @@ func (g *Graphics) draw(dst *Image, dstRegions []graphicsdriver.DstRegion, srcs
return err
}
drawWithStencilRpss = s
} else {
s, err := shader.RenderPipelineState(&g.view, blend, noStencil, dst.screen)
if err != nil {
return err
}
noStencilRpss = s
}
for _, dstRegion := range dstRegions {
@ -571,7 +572,12 @@ func (g *Graphics) draw(dst *Image, dstRegions []graphicsdriver.DstRegion, srcs
Height: dstRegion.Region.Dy(),
})
if evenOdd {
switch fillRule {
case graphicsdriver.FillAll:
g.rce.SetDepthStencilState(g.dsss[noStencil])
g.rce.SetRenderPipelineState(noStencilRpss)
g.rce.DrawIndexedPrimitives(mtl.PrimitiveTypeTriangle, dstRegion.IndexCount, mtl.IndexTypeUInt32, g.ib, indexOffset*int(unsafe.Sizeof(uint32(0))))
case graphicsdriver.EvenOdd:
g.rce.SetDepthStencilState(g.dsss[prepareStencil])
g.rce.SetRenderPipelineState(prepareStencilRpss)
g.rce.DrawIndexedPrimitives(mtl.PrimitiveTypeTriangle, dstRegion.IndexCount, mtl.IndexTypeUInt32, g.ib, indexOffset*int(unsafe.Sizeof(uint32(0))))
@ -579,10 +585,6 @@ func (g *Graphics) draw(dst *Image, dstRegions []graphicsdriver.DstRegion, srcs
g.rce.SetDepthStencilState(g.dsss[drawWithStencil])
g.rce.SetRenderPipelineState(drawWithStencilRpss)
g.rce.DrawIndexedPrimitives(mtl.PrimitiveTypeTriangle, dstRegion.IndexCount, mtl.IndexTypeUInt32, g.ib, indexOffset*int(unsafe.Sizeof(uint32(0))))
} else {
g.rce.SetDepthStencilState(g.dsss[noStencil])
g.rce.SetRenderPipelineState(noStencilRpss)
g.rce.DrawIndexedPrimitives(mtl.PrimitiveTypeTriangle, dstRegion.IndexCount, mtl.IndexTypeUInt32, g.ib, indexOffset*int(unsafe.Sizeof(uint32(0))))
}
indexOffset += dstRegion.IndexCount
@ -591,7 +593,7 @@ func (g *Graphics) draw(dst *Image, dstRegions []graphicsdriver.DstRegion, srcs
return nil
}
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, evenOdd bool) error {
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
if shaderID == graphicsdriver.InvalidShaderID {
return fmt.Errorf("metal: shader ID is invalid")
}
@ -667,7 +669,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
idx += n
}
if err := g.draw(dst, dstRegions, srcs, indexOffset, g.shaders[shaderID], uniformVars, blend, evenOdd); err != nil {
if err := g.draw(dst, dstRegions, srcs, indexOffset, g.shaders[shaderID], uniformVars, blend, fillRule); err != nil {
return err
}

View File

@ -182,7 +182,7 @@ func (g *Graphics) uniformVariableName(idx int) string {
return name
}
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, evenOdd bool) error {
func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.ShaderImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
if shaderID == graphicsdriver.InvalidShaderID {
return fmt.Errorf("opengl: shader ID is invalid")
}
@ -243,7 +243,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
}
g.uniformVars = g.uniformVars[:0]
if evenOdd {
if fillRule == graphicsdriver.EvenOdd {
if err := destination.ensureStencilBuffer(); err != nil {
return err
}
@ -257,7 +257,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
int32(dstRegion.Region.Dx()),
int32(dstRegion.Region.Dy()),
)
if evenOdd {
if fillRule == graphicsdriver.EvenOdd {
g.context.ctx.Clear(gl.STENCIL_BUFFER_BIT)
g.context.ctx.StencilFunc(gl.ALWAYS, 0x00, 0xff)
g.context.ctx.StencilOp(gl.KEEP, gl.KEEP, gl.INVERT)
@ -273,7 +273,7 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
indexOffset += dstRegion.IndexCount
}
if evenOdd {
if fillRule == graphicsdriver.EvenOdd {
g.context.ctx.Disable(gl.STENCIL_TEST)
}

View File

@ -65,7 +65,7 @@ func (m *Mipmap) ReadPixels(graphicsDriver graphicsdriver.Graphics, pixels []byt
return m.orig.ReadPixels(graphicsDriver, pixels, region)
}
func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderImageCount]*Mipmap, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *atlas.Shader, uniforms []uint32, evenOdd bool, canSkipMipmap bool) {
func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderImageCount]*Mipmap, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *atlas.Shader, uniforms []uint32, fillRule graphicsdriver.FillRule, canSkipMipmap bool) {
if len(indices) == 0 {
return
}
@ -123,7 +123,7 @@ func (m *Mipmap) DrawTriangles(srcs [graphics.ShaderImageCount]*Mipmap, vertices
imgs[i] = src.orig
}
m.orig.DrawTriangles(imgs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, evenOdd)
m.orig.DrawTriangles(imgs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule)
m.deallocateMipmaps()
}
@ -187,7 +187,7 @@ func (m *Mipmap) level(level int) *buffered.Image {
s := buffered.NewImage(w2, h2, m.imageType)
dstRegion := image.Rect(0, 0, w2, h2)
s.DrawTriangles([graphics.ShaderImageCount]*buffered.Image{src}, vs, is, graphicsdriver.BlendCopy, dstRegion, [graphics.ShaderImageCount]image.Rectangle{}, shader, nil, false)
s.DrawTriangles([graphics.ShaderImageCount]*buffered.Image{src}, vs, is, graphicsdriver.BlendCopy, dstRegion, [graphics.ShaderImageCount]image.Rectangle{}, shader, nil, graphicsdriver.FillAll)
m.setImg(level, s)
return m.imgs[level]

View File

@ -87,7 +87,7 @@ type drawTrianglesHistoryItem struct {
srcRegions [graphics.ShaderImageCount]image.Rectangle
shader *Shader
uniforms []uint32
evenOdd bool
fillRule graphicsdriver.FillRule
}
type ImageType int
@ -187,7 +187,7 @@ func (i *Image) Extend(width, height int) *Image {
vs := quadVertices(0, 0, float32(sw), float32(sh), 0, 0, float32(sw), float32(sh), 1, 1, 1, 1)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, sw, sh)
newImg.DrawTriangles(srcs, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader, nil, false)
newImg.DrawTriangles(srcs, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader, nil, graphicsdriver.FillAll)
i.Dispose()
return newImg
@ -206,7 +206,7 @@ func quadVertices(dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1, cr, cg, cb, ca float32
func clearImage(i *graphicscommand.Image, region image.Rectangle) {
vs := quadVertices(float32(region.Min.X), float32(region.Min.Y), float32(region.Max.X), float32(region.Max.Y), 0, 0, 0, 0, 0, 0, 0, 0)
is := graphics.QuadIndices()
i.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{}, vs, is, graphicsdriver.BlendClear, region, [graphics.ShaderImageCount]image.Rectangle{}, clearShader.shader, nil, false)
i.DrawTriangles([graphics.ShaderImageCount]*graphicscommand.Image{}, vs, is, graphicsdriver.BlendClear, region, [graphics.ShaderImageCount]image.Rectangle{}, clearShader.shader, nil, graphicsdriver.FillAll)
}
// BasePixelsForTesting returns the image's basePixels for testing.
@ -322,7 +322,7 @@ func (i *Image) WritePixels(pixels *graphics.ManagedBytes, region image.Rectangl
// 5: Color G
// 6: Color B
// 7: Color Y
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, evenOdd bool) {
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) {
if len(vertices) == 0 {
return
}
@ -344,7 +344,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices [
if srcstale || !needsRestoring() || !i.needsRestoring() || i.stale {
i.makeStale(dstRegion)
} else {
i.appendDrawTrianglesHistory(srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, evenOdd)
i.appendDrawTrianglesHistory(srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule)
}
var imgs [graphics.ShaderImageCount]*graphicscommand.Image
@ -354,11 +354,11 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices [
}
imgs[i] = src.image
}
i.image.DrawTriangles(imgs, vertices, indices, blend, dstRegion, srcRegions, shader.shader, uniforms, evenOdd)
i.image.DrawTriangles(imgs, vertices, indices, blend, dstRegion, srcRegions, shader.shader, uniforms, fillRule)
}
// appendDrawTrianglesHistory appends a draw-image history item to the image.
func (i *Image) appendDrawTrianglesHistory(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, evenOdd bool) {
func (i *Image) appendDrawTrianglesHistory(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule) {
if i.stale || !i.needsRestoring() {
panic("restorable: an image must not be stale or need restoring at appendDrawTrianglesHistory")
}
@ -393,7 +393,7 @@ func (i *Image) appendDrawTrianglesHistory(srcs [graphics.ShaderImageCount]*Imag
srcRegions: srcRegions,
shader: shader,
uniforms: us,
evenOdd: evenOdd,
fillRule: fillRule,
}
i.drawTrianglesHistory = append(i.drawTrianglesHistory, item)
}
@ -610,7 +610,7 @@ func (i *Image) restore(graphicsDriver graphicsdriver.Graphics) error {
}
imgs[i] = img.image
}
gimg.DrawTriangles(imgs, c.vertices, c.indices, c.blend, c.dstRegion, c.srcRegions, c.shader.shader, c.uniforms, c.evenOdd)
gimg.DrawTriangles(imgs, c.vertices, c.indices, c.blend, c.dstRegion, c.srcRegions, c.shader.shader, c.uniforms, c.fillRule)
}
// In order to clear the draw-triangles history, read pixels from GPU.

View File

@ -143,7 +143,7 @@ func TestRestoreChain(t *testing.T) {
vs := quadVertices(1, 1, 0, 0)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, 1, 1)
imgs[i+1].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[i]}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
imgs[i+1].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[i]}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
}
if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil {
t.Fatal(err)
@ -186,10 +186,10 @@ func TestRestoreChain2(t *testing.T) {
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
imgs[8].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[7]}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
imgs[9].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[8]}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
imgs[8].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[7]}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
imgs[9].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[8]}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
for i := 0; i < 7; i++ {
imgs[i+1].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[i]}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
imgs[i+1].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[i]}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
}
if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil {
@ -230,10 +230,10 @@ func TestRestoreOverrideSource(t *testing.T) {
img1.WritePixels(bytesToManagedBytes([]byte{clr0.R, clr0.G, clr0.B, clr0.A}), image.Rect(0, 0, w, h))
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
img2.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img3.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img2.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
img3.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
img0.WritePixels(bytesToManagedBytes([]byte{clr1.R, clr1.G, clr1.B, clr1.A}), image.Rect(0, 0, w, h))
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, quadVertices(w, h, 0, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil {
t.Fatal(err)
}
@ -313,23 +313,23 @@ func TestRestoreComplexGraph(t *testing.T) {
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
vs := quadVertices(w, h, 0, 0)
img3.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img3.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
vs = quadVertices(w, h, 1, 0)
img3.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img3.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
vs = quadVertices(w, h, 1, 0)
img4.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img4.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
vs = quadVertices(w, h, 2, 0)
img4.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img4.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
vs = quadVertices(w, h, 0, 0)
img5.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img3}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img5.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img3}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
vs = quadVertices(w, h, 0, 0)
img6.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img3}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img6.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img3}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
vs = quadVertices(w, h, 1, 0)
img6.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img4}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img6.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img4}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
vs = quadVertices(w, h, 0, 0)
img7.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img7.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
vs = quadVertices(w, h, 2, 0)
img7.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img3}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img7.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img3}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil {
t.Fatal(err)
}
@ -422,8 +422,8 @@ func TestRestoreRecursive(t *testing.T) {
}()
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, quadVertices(w, h, 1, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img0.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, quadVertices(w, h, 1, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, quadVertices(w, h, 1, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
img0.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, quadVertices(w, h, 1, 0), is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil {
t.Fatal(err)
}
@ -522,7 +522,7 @@ func TestDrawTrianglesAndWritePixels(t *testing.T) {
vs := quadVertices(1, 1, 0, 0)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, 2, 1)
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
img1.WritePixels(bytesToManagedBytes([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}), image.Rect(0, 0, 2, 1))
if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil {
@ -560,8 +560,8 @@ func TestDispose(t *testing.T) {
is := graphics.QuadIndices()
dr := image.Rect(0, 0, 1, 1)
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, quadVertices(1, 1, 0, 0), is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img0.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, quadVertices(1, 1, 0, 0), is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img2}, quadVertices(1, 1, 0, 0), is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
img0.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img1}, quadVertices(1, 1, 0, 0), is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
img1.Dispose()
if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil {
@ -670,7 +670,7 @@ func TestWritePixelsOnly(t *testing.T) {
vs := quadVertices(1, 1, 0, 0)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, 1, 1)
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img1.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{img0}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
img0.WritePixels(bytesToManagedBytes([]byte{5, 6, 7, 8}), image.Rect(0, 0, 1, 1))
// BasePixelsForTesting is available without GPU accessing.
@ -724,7 +724,7 @@ func TestReadPixelsFromVolatileImage(t *testing.T) {
vs := quadVertices(1, 1, 0, 0)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
// Read the pixels. If the implementation is correct, dst tries to read its pixels from GPU due to being
// stale.
@ -748,7 +748,7 @@ func TestAllowWritePixelsAfterDrawTriangles(t *testing.T) {
vs := quadVertices(w, h, 0, 0)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
dst.WritePixels(bytesToManagedBytes(make([]byte, 4*w*h)), image.Rect(0, 0, w, h))
// WritePixels for a whole image doesn't panic.
}
@ -767,7 +767,7 @@ func TestAllowWritePixelsForPartAfterDrawTriangles(t *testing.T) {
vs := quadVertices(w, h, 0, 0)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
dst.WritePixels(bytesToManagedBytes(make([]byte, 4*2*2)), image.Rect(0, 0, 2, 2))
// WritePixels for a part of image doesn't panic.
@ -861,7 +861,7 @@ func TestDrawTrianglesAndExtend(t *testing.T) {
vs := quadVertices(w, h, 0, 0)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
orig.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
orig.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
extended := orig.Extend(w*2, h*2) // After this, orig is already disposed.
result := make([]byte, 4*(w*2)*(h*2))
@ -911,7 +911,7 @@ func TestMutateSlices(t *testing.T) {
is := make([]uint32, len(graphics.QuadIndices()))
copy(is, graphics.QuadIndices())
dr := image.Rect(0, 0, w, h)
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
for i := range vs {
vs[i] = 0
}
@ -1103,7 +1103,7 @@ func TestDrawTrianglesAndReadPixels(t *testing.T) {
vs := quadVertices(w, h, 0, 0)
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
pix := make([]byte, 4*w*h)
if err := dst.ReadPixels(ui.Get().GraphicsDriverForTesting(), pix, image.Rect(0, 0, w, h)); err != nil {
@ -1127,7 +1127,7 @@ func TestWritePixelsAndDrawTriangles(t *testing.T) {
vs := quadVertices(1, 1, 1, 0)
is := graphics.QuadIndices()
dr := image.Rect(1, 0, 2, 1)
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
dst.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{src}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
// Get the pixels.
pix := make([]byte, 4*2*1)

View File

@ -46,7 +46,7 @@ func clearImage(img *restorable.Image, w, h int) {
}
is := graphics.QuadIndices()
dr := image.Rect(0, 0, w, h)
img.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{emptyImage}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, false)
img.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{emptyImage}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderImageCount]image.Rectangle{}, restorable.NearestFilterShader, nil, graphicsdriver.FillAll)
}
func TestShader(t *testing.T) {
@ -55,7 +55,7 @@ func TestShader(t *testing.T) {
s := restorable.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff))
dr := image.Rect(0, 0, 1, 1)
img.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, false)
img.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillAll)
if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil {
t.Fatal(err)
@ -85,7 +85,7 @@ func TestShaderChain(t *testing.T) {
s := restorable.NewShader(etesting.ShaderProgramImages(1))
for i := 0; i < num-1; i++ {
dr := image.Rect(0, 0, 1, 1)
imgs[i+1].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[i]}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, false)
imgs[i+1].DrawTriangles([graphics.ShaderImageCount]*restorable.Image{imgs[i]}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillAll)
}
if err := restorable.ResolveStaleImages(ui.Get().GraphicsDriverForTesting()); err != nil {
@ -117,7 +117,7 @@ func TestShaderMultipleSources(t *testing.T) {
s := restorable.NewShader(etesting.ShaderProgramImages(3))
dr := image.Rect(0, 0, 1, 1)
dst.DrawTriangles(srcs, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, false)
dst.DrawTriangles(srcs, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillAll)
// Clear one of the sources after DrawTriangles. dst should not be affected.
clearImage(srcs[0], 1, 1)
@ -154,7 +154,7 @@ func TestShaderMultipleSourcesOnOneTexture(t *testing.T) {
image.Rect(1, 0, 2, 1),
image.Rect(2, 0, 3, 1),
}
dst.DrawTriangles(srcs, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, srcRegions, s, nil, false)
dst.DrawTriangles(srcs, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, srcRegions, s, nil, graphicsdriver.FillAll)
// Clear one of the sources after DrawTriangles. dst should not be affected.
clearImage(srcs[0], 3, 1)
@ -179,7 +179,7 @@ func TestShaderDispose(t *testing.T) {
s := restorable.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff))
dr := image.Rect(0, 0, 1, 1)
img.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, false)
img.DrawTriangles([graphics.ShaderImageCount]*restorable.Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillAll)
// Dispose the shader. This should invalidate all the images using this shader i.e., all the images become
// stale.

View File

@ -80,7 +80,7 @@ func (i *Image) Deallocate() {
i.dotsBuffer = nil
}
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, evenOdd bool, canSkipMipmap bool, antialias bool) {
func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule, canSkipMipmap bool, antialias bool) {
if i.modifyCallback != nil {
i.modifyCallback()
}
@ -104,7 +104,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices [
i.bigOffscreenBuffer = i.ui.newBigOffscreenImage(i, imageType)
}
i.bigOffscreenBuffer.drawTriangles(srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, evenOdd, canSkipMipmap, false)
i.bigOffscreenBuffer.drawTriangles(srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule, canSkipMipmap, false)
return
}
@ -119,7 +119,7 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices [
srcMipmaps[i] = src.mipmap
}
i.mipmap.DrawTriangles(srcMipmaps, vertices, indices, blend, dstRegion, srcRegions, shader.shader, uniforms, evenOdd, canSkipMipmap)
i.mipmap.DrawTriangles(srcMipmaps, vertices, indices, blend, dstRegion, srcRegions, shader.shader, uniforms, fillRule, canSkipMipmap)
}
func (i *Image) WritePixels(pix []byte, region image.Rectangle) {
@ -253,7 +253,7 @@ func (i *Image) flushDotsBufferIfNeeded() {
dr := image.Rect(0, 0, i.width, i.height)
blend := graphicsdriver.BlendCopy
i.lastBlend = blend
i.mipmap.DrawTriangles(srcs, vs, is, blend, dr, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader.shader, nil, false, true)
i.mipmap.DrawTriangles(srcs, vs, is, blend, dr, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader.shader, nil, graphicsdriver.FillAll, true)
}
func (i *Image) flushBigOffscreenBufferIfNeeded() {
@ -290,7 +290,7 @@ func (i *Image) Fill(r, g, b, a float32, region image.Rectangle) {
blend = graphicsdriver.BlendSourceOver
}
// i.lastBlend is updated in DrawTriangles.
i.DrawTriangles(srcs, i.tmpVerticesForFill, is, blend, region, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader, nil, false, true, false)
i.DrawTriangles(srcs, i.tmpVerticesForFill, is, blend, region, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader, nil, graphicsdriver.FillAll, true, false)
}
type bigOffscreenImage struct {
@ -324,7 +324,7 @@ func (i *bigOffscreenImage) deallocate() {
i.dirty = false
}
func (i *bigOffscreenImage) drawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, evenOdd bool, canSkipMipmap bool, antialias bool) {
func (i *bigOffscreenImage) drawTriangles(srcs [graphics.ShaderImageCount]*Image, vertices []float32, indices []uint32, blend graphicsdriver.Blend, dstRegion image.Rectangle, srcRegions [graphics.ShaderImageCount]image.Rectangle, shader *Shader, uniforms []uint32, fillRule graphicsdriver.FillRule, canSkipMipmap bool, antialias bool) {
if i.blend != blend {
i.flush()
}
@ -359,7 +359,7 @@ func (i *bigOffscreenImage) drawTriangles(srcs [graphics.ShaderImageCount]*Image
1, 1, 1, 1)
is := graphics.QuadIndices()
dstRegion := image.Rect(0, 0, i.region.Dx()*bigOffscreenScale, i.region.Dy()*bigOffscreenScale)
i.image.DrawTriangles(srcs, i.tmpVerticesForCopying, is, graphicsdriver.BlendCopy, dstRegion, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader, nil, false, true, false)
i.image.DrawTriangles(srcs, i.tmpVerticesForCopying, is, graphicsdriver.BlendCopy, dstRegion, [graphics.ShaderImageCount]image.Rectangle{}, NearestFilterShader, nil, graphicsdriver.FillAll, true, false)
}
for idx := 0; idx < len(vertices); idx += graphics.VertexFloatCount {
@ -375,7 +375,7 @@ func (i *bigOffscreenImage) drawTriangles(srcs [graphics.ShaderImageCount]*Image
dstRegion.Max.X *= bigOffscreenScale
dstRegion.Max.Y *= bigOffscreenScale
i.image.DrawTriangles(srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, evenOdd, canSkipMipmap, false)
i.image.DrawTriangles(srcs, vertices, indices, blend, dstRegion, srcRegions, shader, uniforms, fillRule, canSkipMipmap, false)
i.dirty = true
}
@ -407,7 +407,7 @@ func (i *bigOffscreenImage) flush() {
if i.blend != graphicsdriver.BlendSourceOver {
blend = graphicsdriver.BlendCopy
}
i.orig.DrawTriangles(srcs, i.tmpVerticesForFlushing, is, blend, dstRegion, [graphics.ShaderImageCount]image.Rectangle{}, LinearFilterShader, nil, false, true, false)
i.orig.DrawTriangles(srcs, i.tmpVerticesForFlushing, is, blend, dstRegion, [graphics.ShaderImageCount]image.Rectangle{}, LinearFilterShader, nil, graphicsdriver.FillAll, true, false)
i.image.clear()
i.dirty = false