Stencil.cpp revision 3bbacf27c0be1bae4e4483577fc89ae3113abe5d
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
173bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#include "Extensions.h"
180baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy#include "Properties.h"
190baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy#include "Stencil.h"
200baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
213bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#include <GLES2/gl2ext.h>
223bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
230baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guynamespace android {
240baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guynamespace uirenderer {
250baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
263bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#if DEBUG_STENCIL
273bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define STENCIL_WRITE_VALUE 0xff
283bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define STENCIL_MASK_VALUE 0xff
293bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#else
303bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define STENCIL_WRITE_VALUE 0x1
313bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define STENCIL_MASK_VALUE 0x1
323bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#endif
333bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
340baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain GuyStencil::Stencil(): mState(kDisabled) {
350baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
360baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
370baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyuint32_t Stencil::getStencilSize() {
380baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    return STENCIL_BUFFER_SIZE;
390baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
400baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
413bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain GuyGLenum Stencil::getSmallestStencilFormat() {
423bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#if !DEBUG_STENCIL
433bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    const Extensions& extensions = Extensions::getInstance();
443bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    if (extensions.has1BitStencil()) {
453bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return GL_STENCIL_INDEX1_OES;
463bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    } else if (extensions.has4BitStencil()) {
473bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return GL_STENCIL_INDEX4_OES;
483bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
493bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#endif
503bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    return GL_STENCIL_INDEX8;
513bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy}
523bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
530baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::clear() {
540baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    glClearStencil(0);
550baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    glClear(GL_STENCIL_BUFFER_BIT);
560baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
570baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
580baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::enableTest() {
590baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    if (mState != kTest) {
600baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        enable();
613bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        glStencilFunc(GL_EQUAL, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE);
620baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        // We only want to test, let's keep everything
630baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
64f7e52d92b41adf460089625ea47bfea2ed7e6296Romain Guy        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
650baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        mState = kTest;
660baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    }
670baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
680baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
690baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::enableWrite() {
700baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    if (mState != kWrite) {
710baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        enable();
723bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        glStencilFunc(GL_ALWAYS, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE);
730baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        // The test always passes so the first two values are meaningless
740baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
75f7e52d92b41adf460089625ea47bfea2ed7e6296Romain Guy        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
760baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        mState = kWrite;
770baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    }
780baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
790baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
807c450aaa3caac2a05fcb20a177483d0e92378426Romain Guyvoid Stencil::enableDebugTest(GLint value, bool greater) {
817c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    enable();
827c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    glStencilFunc(greater ? GL_LESS : GL_EQUAL, value, 0xffffffff);
837c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    // We only want to test, let's keep everything
847c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
857c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    mState = kTest;
867c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy}
877c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy
887c450aaa3caac2a05fcb20a177483d0e92378426Romain Guyvoid Stencil::enableDebugWrite() {
897c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    if (mState != kWrite) {
907c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        enable();
917c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff);
927c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        // The test always passes so the first two values are meaningless
937c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
947c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
957c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        mState = kWrite;
967c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    }
977c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy}
987c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy
990baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::enable() {
1007c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    if (mState == kDisabled) {
1010baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        glEnable(GL_STENCIL_TEST);
1020baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    }
1030baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
1040baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
1050baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::disable() {
1060baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    if (mState != kDisabled) {
1070baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        glDisable(GL_STENCIL_TEST);
1080baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        mState = kDisabled;
1090baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    }
1100baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
1110baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
1120baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}; // namespace uirenderer
1130baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}; // namespace android
114