From f3ef2e2af5aa03aa10b521814e6f7731b2a9451f Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Mon, 21 Sep 2020 05:36:47 +0900 Subject: [PATCH] Performance optimization for the path without a shader Fixes #1355 --- internal/buffered/image.go | 32 +++++++++++++------------- internal/graphicscommand/image.go | 21 +++++++++++++----- internal/restorable/image.go | 19 +++++++++------- internal/shareable/image.go | 37 ++++++++++++++++--------------- 4 files changed, 60 insertions(+), 49 deletions(-) diff --git a/internal/buffered/image.go b/internal/buffered/image.go index 8afe9d410..a9e8d5c41 100644 --- a/internal/buffered/image.go +++ b/internal/buffered/image.go @@ -265,26 +265,24 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f } } - for _, src := range srcs { - if src == nil { - continue - } - src.resolvePendingPixels(true) - } - i.resolvePendingPixels(false) - var s *shareable.Shader - if shader != nil { + var imgs [graphics.ShaderImageNum]*shareable.Image + if shader == nil { + // Fast path for rendering without a shader (#1355). + img := srcs[0] + img.resolvePendingPixels(true) + imgs[0] = img.img + } else { + for i, img := range srcs { + if img == nil { + continue + } + img.resolvePendingPixels(true) + imgs[i] = img.img + } s = shader.shader } - - var imgs [graphics.ShaderImageNum]*shareable.Image - for i, img := range srcs { - if img == nil { - continue - } - imgs[i] = img.img - } + i.resolvePendingPixels(false) i.img.DrawTriangles(imgs, vertices, indices, colorm, mode, filter, address, sourceRegion, subimageOffsets, s, uniforms) i.invalidatePendingPixels() diff --git a/internal/graphicscommand/image.go b/internal/graphicscommand/image.go index 164df5501..02d05f949 100644 --- a/internal/graphicscommand/image.go +++ b/internal/graphicscommand/image.go @@ -157,14 +157,23 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, offsets [gra } } - for _, src := range srcs { - if src == nil { - continue - } - if src.screen { + if shader == nil { + // Fast path for rendering without a shader (#1355). + img := srcs[0] + if img.screen { panic("graphicscommand: the screen image cannot be the rendering source") } - src.resolveBufferedReplacePixels() + img.resolveBufferedReplacePixels() + } else { + for _, src := range srcs { + if src == nil { + continue + } + if src.screen { + panic("graphicscommand: the screen image cannot be the rendering source") + } + src.resolveBufferedReplacePixels() + } } i.resolveBufferedReplacePixels() diff --git a/internal/restorable/image.go b/internal/restorable/image.go index 6147a26e8..16b0a4216 100644 --- a/internal/restorable/image.go +++ b/internal/restorable/image.go @@ -389,17 +389,20 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, offsets [gra } else { i.appendDrawTrianglesHistory(srcs, offsets, vertices, indices, colorm, mode, filter, address, sourceRegion, shader, uniforms) } - var s *graphicscommand.Shader - if shader != nil { - s = shader.shader - } + var s *graphicscommand.Shader var imgs [graphics.ShaderImageNum]*graphicscommand.Image - for i, src := range srcs { - if src == nil { - continue + if shader == nil { + // Fast path for rendering without a shader (#1355). + imgs[0] = srcs[0].image + } else { + for i, src := range srcs { + if src == nil { + continue + } + imgs[i] = src.image } - imgs[i] = src.image + s = shader.shader } i.image.DrawTriangles(imgs, offsets, vertices, indices, colorm, mode, filter, address, sourceRegion, s, uniforms) } diff --git a/internal/shareable/image.go b/internal/shareable/image.go index 97dcbd96a..459821eaf 100644 --- a/internal/shareable/image.go +++ b/internal/shareable/image.go @@ -354,27 +354,28 @@ func (i *Image) DrawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f } var offsets [graphics.ShaderImageNum - 1][2]float32 - for i, subimageOffset := range subimageOffsets { - src := srcs[i+1] - if src == nil { - continue - } - ox, oy, _, _ := src.regionWithPadding() - offsets[i][0] = float32(ox) + paddingSize - oxf + subimageOffset[0] - offsets[i][1] = float32(oy) + paddingSize - oyf + subimageOffset[1] - } - var s *restorable.Shader - if shader != nil { - s = shader.shader - } - var imgs [graphics.ShaderImageNum]*restorable.Image - for i, src := range srcs { - if src == nil { - continue + if shader == nil { + // Fast path for rendering without a shader (#1355). + imgs[0] = srcs[0].backend.restorable + } else { + for i, subimageOffset := range subimageOffsets { + src := srcs[i+1] + if src == nil { + continue + } + ox, oy, _, _ := src.regionWithPadding() + offsets[i][0] = float32(ox) + paddingSize - oxf + subimageOffset[0] + offsets[i][1] = float32(oy) + paddingSize - oyf + subimageOffset[1] + } + s = shader.shader + for i, src := range srcs { + if src == nil { + continue + } + imgs[i] = src.backend.restorable } - imgs[i] = src.backend.restorable } i.backend.restorable.DrawTriangles(imgs, offsets, vertices, indices, colorm, mode, filter, address, sourceRegion, s, uniforms)