| // 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 |
| } |
| } |