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 "Debug.h" 18 #include "Extensions.h" 19 #include "Properties.h" 20 #include "Stencil.h" 21 22 #include <GLES2/gl2ext.h> 23 24 namespace android { 25 namespace uirenderer { 26 27 #if DEBUG_STENCIL 28 #define STENCIL_WRITE_VALUE 0xff 29 #define STENCIL_MASK_VALUE 0xff 30 #else 31 #define STENCIL_WRITE_VALUE 0x1 32 #define STENCIL_MASK_VALUE 0x1 33 #endif 34 35 Stencil::Stencil(): mState(kDisabled) { 36 } 37 38 uint32_t Stencil::getStencilSize() { 39 return STENCIL_BUFFER_SIZE; 40 } 41 42 GLenum Stencil::getSmallestStencilFormat() { 43 #if !DEBUG_STENCIL 44 const Extensions& extensions = Extensions::getInstance(); 45 if (extensions.has1BitStencil()) { 46 return GL_STENCIL_INDEX1_OES; 47 } else if (extensions.has4BitStencil()) { 48 return GL_STENCIL_INDEX4_OES; 49 } 50 #endif 51 return GL_STENCIL_INDEX8; 52 } 53 54 void Stencil::clear() { 55 glClearStencil(0); 56 glClear(GL_STENCIL_BUFFER_BIT); 57 } 58 59 void Stencil::enableTest() { 60 if (mState != kTest) { 61 enable(); 62 glStencilFunc(GL_EQUAL, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE); 63 // We only want to test, let's keep everything 64 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 65 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 66 mState = kTest; 67 } 68 } 69 70 void Stencil::enableWrite() { 71 if (mState != kWrite) { 72 enable(); 73 glStencilFunc(GL_ALWAYS, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE); 74 // The test always passes so the first two values are meaningless 75 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 76 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 77 mState = kWrite; 78 } 79 } 80 81 void Stencil::enableDebugTest(GLint value, bool greater) { 82 enable(); 83 glStencilFunc(greater ? GL_LESS : GL_EQUAL, value, 0xffffffff); 84 // We only want to test, let's keep everything 85 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 86 mState = kTest; 87 } 88 89 void Stencil::enableDebugWrite() { 90 if (mState != kWrite) { 91 enable(); 92 glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff); 93 // The test always passes so the first two values are meaningless 94 glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); 95 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 96 mState = kWrite; 97 } 98 } 99 100 void Stencil::enable() { 101 if (mState == kDisabled) { 102 glEnable(GL_STENCIL_TEST); 103 } 104 } 105 106 void Stencil::disable() { 107 if (mState != kDisabled) { 108 glDisable(GL_STENCIL_TEST); 109 mState = kDisabled; 110 } 111 } 112 113 }; // namespace uirenderer 114 }; // namespace android 115