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
Stencil()34 Stencil::Stencil(): mState(kDisabled) {
35 }
36
getStencilSize()37 uint32_t Stencil::getStencilSize() {
38 return STENCIL_BUFFER_SIZE;
39 }
40
getSmallestStencilFormat()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
clear()53 void Stencil::clear() {
54 glClearStencil(0);
55 glClear(GL_STENCIL_BUFFER_BIT);
56 }
57
enableTest()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
enableWrite()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
enableDebugTest(GLint value,bool greater)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
enableDebugWrite()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
enable()99 void Stencil::enable() {
100 if (mState == kDisabled) {
101 glEnable(GL_STENCIL_TEST);
102 }
103 }
104
disable()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