From 71d463c102eeeae65b3c2d63bdc06c80a9d63482 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 3 Jan 2015 15:21:47 +0900 Subject: [PATCH] Avoid copying for performance; Use location caches --- .../graphics/internal/shader/drawtexture.go | 4 ++-- internal/graphics/internal/shader/program.go | 8 +++---- internal/opengl/context.go | 19 +++++++++++---- internal/opengl/context_js.go | 24 +++++++++++++++---- internal/opengl/locationcache.go | 22 +++++++++++++++++ 5 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 internal/opengl/locationcache.go diff --git a/internal/graphics/internal/shader/drawtexture.go b/internal/graphics/internal/shader/drawtexture.go index dc1893339..71b786a4b 100644 --- a/internal/graphics/internal/shader/drawtexture.go +++ b/internal/graphics/internal/shader/drawtexture.go @@ -18,8 +18,8 @@ import ( "github.com/hajimehoshi/ebiten/internal/opengl" ) -func glMatrix(m *[4][4]float64) [16]float32 { - result := [16]float32{} +func glMatrix(m *[4][4]float64) []float32 { + result := make([]float32, 16) for j := 0; j < 4; j++ { for i := 0; i < 4; i++ { result[i+j*4] = float32(m[i][j]) diff --git a/internal/graphics/internal/shader/program.go b/internal/graphics/internal/shader/program.go index 96901b31f..f181610a6 100644 --- a/internal/graphics/internal/shader/program.go +++ b/internal/graphics/internal/shader/program.go @@ -65,7 +65,7 @@ func initialize(c *opengl.Context) error { var lastProgram opengl.Program -func useProgramColorMatrix(c *opengl.Context, projectionMatrix [16]float32, geo Matrix, color Matrix) opengl.Program { +func useProgramColorMatrix(c *opengl.Context, projectionMatrix []float32, geo Matrix, color Matrix) opengl.Program { if lastProgram != programColorMatrix { c.UseProgram(programColorMatrix) lastProgram = programColorMatrix @@ -81,7 +81,7 @@ func useProgramColorMatrix(c *opengl.Context, projectionMatrix [16]float32, geo md := float32(geo.Element(1, 1)) tx := float32(geo.Element(0, 2)) ty := float32(geo.Element(1, 2)) - glModelviewMatrix := [...]float32{ + glModelviewMatrix := []float32{ ma, mc, 0, 0, mb, md, 0, 0, 0, 0, 1, 0, @@ -97,14 +97,14 @@ func useProgramColorMatrix(c *opengl.Context, projectionMatrix [16]float32, geo } } - glColorMatrix := [...]float32{ + glColorMatrix := []float32{ e[0][0], e[1][0], e[2][0], e[3][0], e[0][1], e[1][1], e[2][1], e[3][1], e[0][2], e[1][2], e[2][2], e[3][2], e[0][3], e[1][3], e[2][3], e[3][3], } c.Uniform(program, "color_matrix", glColorMatrix) - glColorMatrixTranslation := [...]float32{ + glColorMatrixTranslation := []float32{ e[0][4], e[1][4], e[2][4], e[3][4], } c.Uniform(program, "color_matrix_translation", glColorMatrixTranslation) diff --git a/internal/opengl/context.go b/internal/opengl/context.go index 77b6883b6..8630ea71c 100644 --- a/internal/opengl/context.go +++ b/internal/opengl/context.go @@ -26,6 +26,8 @@ type Texture int type Framebuffer int type Shader int type Program int +type UniformLocation int +type AttribLocation int type context struct{} @@ -177,10 +179,19 @@ func (c *Context) Uniform(p Program, location string, v interface{}) { switch v := v.(type) { case int: l.Uniform1i(v) - case [4]float32: - l.Uniform4fv(1, v[:]) - case [16]float32: - l.UniformMatrix4fv(false, v) + case []float32: + switch len(v) { + case 4: + l.Uniform4fv(1, v) + case 16: + v2 := [16]float32{} + copy(v2[:], v) + l.UniformMatrix4fv(false, v2) + default: + panic("not reach") + } + default: + panic("not reach") } } diff --git a/internal/opengl/context_js.go b/internal/opengl/context_js.go index f7e8e02a2..9864a84dd 100644 --- a/internal/opengl/context_js.go +++ b/internal/opengl/context_js.go @@ -27,6 +27,8 @@ type Texture js.Object type Framebuffer js.Object type Shader js.Object type Program js.Object +type UniformLocation js.Object +type AttribLocation js.Object type context struct { gl *webgl.Context @@ -196,14 +198,26 @@ func (c *Context) UseProgram(p Program) { func (c *Context) Uniform(p Program, location string, v interface{}) { gl := c.gl - l := gl.GetUniformLocation(p, location) + key := locationCacheKey{p, location} + l, ok := uniformLocationCache[key] + if !ok { + l = gl.GetUniformLocation(p, location) + uniformLocationCache[key] = l + } switch v := v.(type) { case int: gl.Uniform1i(l, v) - case [4]float32: - gl.Call("uniform4fv", l, v[:]) - case [16]float32: - gl.UniformMatrix4fv(l, false, v[:]) + case []float32: + switch len(v) { + case 4: + gl.Call("uniform4fv", l, v) + case 16: + gl.UniformMatrix4fv(l, false, v) + default: + panic("not reach") + } + default: + panic("not reach") } } diff --git a/internal/opengl/locationcache.go b/internal/opengl/locationcache.go new file mode 100644 index 000000000..6d02fb523 --- /dev/null +++ b/internal/opengl/locationcache.go @@ -0,0 +1,22 @@ +// Copyright 2014 Hajime Hoshi +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package opengl + +type locationCacheKey struct { + program Program + name string +} + +var uniformLocationCache = map[locationCacheKey]UniformLocation{}