blob: 8ef62865257e00a9b41036f6bb5b94e5be961b35 [file] [log] [blame]
// 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 GLfloat) {
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
}
}