Stencil.cpp revision 117bdbcfa3e8306dad21e7e01fa71b00cdfa7265
10baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy/* 20baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * Copyright (C) 2012 The Android Open Source Project 30baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * 40baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 50baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * you may not use this file except in compliance with the License. 60baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * You may obtain a copy of the License at 70baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * 80baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 90baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * 100baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * Unless required by applicable law or agreed to in writing, software 110baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 120baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * See the License for the specific language governing permissions and 140baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy * limitations under the License. 150baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy */ 160baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy 17117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik#include "renderstate/Stencil.h" 18117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik 19117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik#include "Caches.h" 20b7b93e00893f5c690a96bd3e0e10583bc5721f83Romain Guy#include "Debug.h" 213bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#include "Extensions.h" 220baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy#include "Properties.h" 230baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy 243bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#include <GLES2/gl2ext.h> 253bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 260baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guynamespace android { 270baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guynamespace uirenderer { 280baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy 293bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#if DEBUG_STENCIL 303bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define STENCIL_WRITE_VALUE 0xff 313bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define STENCIL_MASK_VALUE 0xff 323bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#else 333bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define STENCIL_WRITE_VALUE 0x1 343bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define STENCIL_MASK_VALUE 0x1 353bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#endif 363bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 37487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob TsukStencil::Stencil() 38487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk : mState(kDisabled) { 390baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy} 400baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy 4123b797ab5151eb2474f3bdd679f2f07bfd723042John Reckuint8_t Stencil::getStencilSize() { 420baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy return STENCIL_BUFFER_SIZE; 430baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy} 440baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy 453bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain GuyGLenum Stencil::getSmallestStencilFormat() { 463bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#if !DEBUG_STENCIL 47117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik const Extensions& extensions = Caches::getInstance().extensions(); 483bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy if (extensions.has1BitStencil()) { 493bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy return GL_STENCIL_INDEX1_OES; 503bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } else if (extensions.has4BitStencil()) { 513bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy return GL_STENCIL_INDEX4_OES; 523bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy } 533bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#endif 543bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy return GL_STENCIL_INDEX8; 553bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy} 563bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy 570baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::clear() { 580baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy glClearStencil(0); 590baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy glClear(GL_STENCIL_BUFFER_BIT); 600baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy} 610baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy 62487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukvoid Stencil::enableTest(int incrementThreshold) { 630baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy if (mState != kTest) { 640baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy enable(); 65487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk if (incrementThreshold > 0) { 66487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk glStencilFunc(GL_EQUAL, incrementThreshold, 0xff); 67487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } else { 68487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk glStencilFunc(GL_EQUAL, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE); 69487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } 700baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy // We only want to test, let's keep everything 710baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 72f7e52d92b41adf460089625ea47bfea2ed7e6296Romain Guy glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 73487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk glStencilMask(0); 740baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy mState = kTest; 750baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy } 760baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy} 770baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy 78487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsukvoid Stencil::enableWrite(int incrementThreshold) { 790baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy if (mState != kWrite) { 800baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy enable(); 81487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk if (incrementThreshold > 0) { 82487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk glStencilFunc(GL_ALWAYS, 1, 0xff); 83487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk // The test always passes so the first two values are meaningless 84487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk glStencilOp(GL_INCR, GL_INCR, GL_INCR); 85487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } else { 86487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk glStencilFunc(GL_ALWAYS, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE); 87487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk // The test always passes so the first two values are meaningless 88487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 89487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk } 90f7e52d92b41adf460089625ea47bfea2ed7e6296Romain Guy glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 91487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk glStencilMask(0xff); 920baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy mState = kWrite; 930baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy } 940baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy} 950baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy 967c450aaa3caac2a05fcb20a177483d0e92378426Romain Guyvoid Stencil::enableDebugTest(GLint value, bool greater) { 977c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy enable(); 987c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy glStencilFunc(greater ? GL_LESS : GL_EQUAL, value, 0xffffffff); 997c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy // We only want to test, let's keep everything 1007c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 1017c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy mState = kTest; 1027c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy} 1037c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy 1047c450aaa3caac2a05fcb20a177483d0e92378426Romain Guyvoid Stencil::enableDebugWrite() { 1057c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy if (mState != kWrite) { 1067c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy enable(); 1077c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff); 1087c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy // The test always passes so the first two values are meaningless 1097c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); 1107c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 1117c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy mState = kWrite; 1127c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy } 1137c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy} 1147c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy 1150baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::enable() { 1167c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy if (mState == kDisabled) { 1170baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy glEnable(GL_STENCIL_TEST); 1180baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy } 1190baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy} 1200baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy 1210baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::disable() { 1220baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy if (mState != kDisabled) { 1230baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy glDisable(GL_STENCIL_TEST); 1240baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy mState = kDisabled; 1250baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy } 1260baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy} 1270baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy 128117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craikvoid Stencil::dump() { 129117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik ALOGD("Stencil: state %d", mState); 130117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik} 131117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik 1320baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}; // namespace uirenderer 1330baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}; // namespace android 134