Merge "Add gles.tweaker for temporarily tweaking things." into studio-1.4-dev
diff --git a/gfxapi/gles/tweaker.go b/gfxapi/gles/tweaker.go
new file mode 100644
index 0000000..727c8c0
--- /dev/null
+++ b/gfxapi/gles/tweaker.go
@@ -0,0 +1,114 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// 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 gles
+
+import "android.googlesource.com/platform/tools/gpu/atom"
+
+// tweaker provides a set of methods for temporarily changing the GLES state.
+type tweaker struct {
+ out atom.Writer
+ ctx *Context
+ undo []func()
+}
+
+// revert undoes all the changes made by the tweaker.
+func (t *tweaker) revert() {
+ for i := len(t.undo) - 1; i >= 0; i-- {
+ t.undo[i]()
+ }
+ t.undo = nil
+}
+
+func (t *tweaker) glEnable(v GLenum) {
+ if !t.ctx.Capabilities[v] {
+ t.undo = append(t.undo, func() {
+ t.out.Write(atom.NoID, NewGlDisable(v))
+ t.ctx.Capabilities[v] = false
+ })
+ t.out.Write(atom.NoID, NewGlEnable(v))
+ t.ctx.Capabilities[v] = true
+ }
+}
+
+func (t *tweaker) glDisable(v GLenum) {
+ if t.ctx.Capabilities[v] {
+ t.undo = append(t.undo, func() {
+ t.out.Write(atom.NoID, NewGlEnable(v))
+ t.ctx.Capabilities[v] = true
+ })
+ t.out.Write(atom.NoID, NewGlDisable(v))
+ t.ctx.Capabilities[v] = false
+ }
+}
+
+func (t *tweaker) glDepthMask(v bool) {
+ if o := t.ctx.Rasterizing.DepthMask; o != v {
+ t.undo = append(t.undo, func() {
+ t.out.Write(atom.NoID, NewGlDepthMask(o))
+ t.ctx.Rasterizing.DepthMask = o
+ })
+ t.out.Write(atom.NoID, NewGlDepthMask(v))
+ t.ctx.Rasterizing.DepthMask = v
+ }
+}
+
+func (t *tweaker) glDepthFunc(v GLenum) {
+ if o := t.ctx.Rasterizing.DepthTestFunction; o != v {
+ t.undo = append(t.undo, func() {
+ t.out.Write(atom.NoID, NewGlDepthFunc(o))
+ t.ctx.Rasterizing.DepthTestFunction = o
+ })
+ t.out.Write(atom.NoID, NewGlDepthFunc(v))
+ t.ctx.Rasterizing.DepthTestFunction = v
+ }
+}
+
+func (t *tweaker) glBlendColor(r, g, b, a float32) {
+ n := Color{Red: r, Green: g, Blue: b, Alpha: a}
+ if o := t.ctx.Blending.BlendColor; o != n {
+ t.undo = append(t.undo, func() {
+ t.out.Write(atom.NoID, NewGlBlendColor(o.Red, o.Green, o.Blue, o.Alpha))
+ t.ctx.Blending.BlendColor = o
+ })
+ t.out.Write(atom.NoID, NewGlBlendColor(r, g, b, a))
+ t.ctx.Blending.BlendColor = n
+ }
+}
+
+func (t *tweaker) glBlendFunc(src, dst GLenum) {
+ t.glBlendFuncSeparate(src, dst, src, dst)
+}
+
+func (t *tweaker) glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA GLenum) {
+ oSrcRGB, oDstRGB, oSrcA, oDstA :=
+ t.ctx.Blending.SrcRgbBlendFactor,
+ t.ctx.Blending.DstRgbBlendFactor,
+ t.ctx.Blending.SrcAlphaBlendFactor,
+ t.ctx.Blending.DstAlphaBlendFactor
+ if oSrcRGB != srcRGB || oDstRGB != dstRGB || oSrcA != srcA || oDstA != dstA {
+ t.undo = append(t.undo, func() {
+ t.out.Write(atom.NoID, NewGlBlendFuncSeparate(oSrcRGB, oDstRGB, oSrcA, oDstA))
+ t.ctx.Blending.SrcRgbBlendFactor,
+ t.ctx.Blending.DstRgbBlendFactor,
+ t.ctx.Blending.SrcAlphaBlendFactor,
+ t.ctx.Blending.DstAlphaBlendFactor = oSrcRGB, oDstRGB, oSrcA, oDstA
+ })
+ t.out.Write(atom.NoID, NewGlBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA))
+ t.ctx.Blending.SrcRgbBlendFactor,
+ t.ctx.Blending.DstRgbBlendFactor,
+ t.ctx.Blending.SrcAlphaBlendFactor,
+ t.ctx.Blending.DstAlphaBlendFactor = srcRGB, dstRGB, srcA, dstA
+ }
+}