1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "Extensions.h" 18 #include "Properties.h" 19 #include "Stencil.h" 20 21 #include <GLES2/gl2ext.h> 22 23 namespace android { 24 namespace uirenderer { 25 26 #if DEBUG_STENCIL 27 #define STENCIL_WRITE_VALUE 0xff 28 #define STENCIL_MASK_VALUE 0xff 29 #else 30 #define STENCIL_WRITE_VALUE 0x1 31 #define STENCIL_MASK_VALUE 0x1 32 #endif 33 34 Stencil::Stencil(): mState(kDisabled) { 35 } 36 37 uint32_t Stencil::getStencilSize() { 38 return STENCIL_BUFFER_SIZE; 39 } 40 41 GLenum Stencil::getSmallestStencilFormat() { 42 #if !DEBUG_STENCIL 43 const Extensions& extensions = Extensions::getInstance(); 44 if (extensions.has1BitStencil()) { 45 return GL_STENCIL_INDEX1_OES; 46 } else if (extensions.has4BitStencil()) { 47 return GL_STENCIL_INDEX4_OES; 48 } 49 #endif 50 return GL_STENCIL_INDEX8; 51 } 52 53 void Stencil::clear() { 54 glClearStencil(0); 55 glClear(GL_STENCIL_BUFFER_BIT); 56 } 57 58 void Stencil::enableTest() { 59 if (mState != kTest) { 60 enable(); 61 glStencilFunc(GL_EQUAL, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE); 62 // We only want to test, let's keep everything 63 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 64 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 65 mState = kTest; 66 } 67 } 68 69 void Stencil::enableWrite() { 70 if (mState != kWrite) { 71 enable(); 72 glStencilFunc(GL_ALWAYS, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE); 73 // The test always passes so the first two values are meaningless 74 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 75 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 76 mState = kWrite; 77 } 78 } 79 80 void Stencil::enableDebugTest(GLint value, bool greater) { 81 enable(); 82 glStencilFunc(greater ? GL_LESS : GL_EQUAL, value, 0xffffffff); 83 // We only want to test, let's keep everything 84 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 85 mState = kTest; 86 } 87 88 void Stencil::enableDebugWrite() { 89 if (mState != kWrite) { 90 enable(); 91 glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff); 92 // The test always passes so the first two values are meaningless 93 glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); 94 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 95 mState = kWrite; 96 } 97 } 98 99 void Stencil::enable() { 100 if (mState == kDisabled) { 101 glEnable(GL_STENCIL_TEST); 102 } 103 } 104 105 void Stencil::disable() { 106 if (mState != kDisabled) { 107 glDisable(GL_STENCIL_TEST); 108 mState = kDisabled; 109 } 110 } 111 112 }; // namespace uirenderer 113 }; // namespace android 114