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
17b7b93e00893f5c690a96bd3e0e10583bc5721f83Romain Guy#include "Debug.h"
183bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#include "Extensions.h"
190baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy#include "Properties.h"
200baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy#include "Stencil.h"
210baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
223bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#include <GLES2/gl2ext.h>
233bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
240baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guynamespace android {
250baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guynamespace uirenderer {
260baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
273bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#if DEBUG_STENCIL
283bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define STENCIL_WRITE_VALUE 0xff
293bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define STENCIL_MASK_VALUE 0xff
303bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#else
313bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define STENCIL_WRITE_VALUE 0x1
323bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#define STENCIL_MASK_VALUE 0x1
333bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#endif
343bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
350baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain GuyStencil::Stencil(): mState(kDisabled) {
360baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
370baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
3823b797ab5151eb2474f3bdd679f2f07bfd723042John Reckuint8_t Stencil::getStencilSize() {
390baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    return STENCIL_BUFFER_SIZE;
400baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
410baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
423bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain GuyGLenum Stencil::getSmallestStencilFormat() {
433bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#if !DEBUG_STENCIL
443bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    const Extensions& extensions = Extensions::getInstance();
453bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    if (extensions.has1BitStencil()) {
463bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return GL_STENCIL_INDEX1_OES;
473bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    } else if (extensions.has4BitStencil()) {
483bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        return GL_STENCIL_INDEX4_OES;
493bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    }
503bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy#endif
513bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy    return GL_STENCIL_INDEX8;
523bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy}
533bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy
540baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::clear() {
550baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    glClearStencil(0);
560baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    glClear(GL_STENCIL_BUFFER_BIT);
570baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
580baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
590baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::enableTest() {
600baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    if (mState != kTest) {
610baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        enable();
623bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        glStencilFunc(GL_EQUAL, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE);
630baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        // We only want to test, let's keep everything
640baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
65f7e52d92b41adf460089625ea47bfea2ed7e6296Romain Guy        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
660baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        mState = kTest;
670baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    }
680baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
690baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
700baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::enableWrite() {
710baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    if (mState != kWrite) {
720baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        enable();
733bbacf27c0be1bae4e4483577fc89ae3113abe5dRomain Guy        glStencilFunc(GL_ALWAYS, STENCIL_WRITE_VALUE, STENCIL_MASK_VALUE);
740baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        // The test always passes so the first two values are meaningless
750baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
76f7e52d92b41adf460089625ea47bfea2ed7e6296Romain Guy        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
770baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        mState = kWrite;
780baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    }
790baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
800baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
817c450aaa3caac2a05fcb20a177483d0e92378426Romain Guyvoid Stencil::enableDebugTest(GLint value, bool greater) {
827c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    enable();
837c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    glStencilFunc(greater ? GL_LESS : GL_EQUAL, value, 0xffffffff);
847c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    // We only want to test, let's keep everything
857c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
867c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    mState = kTest;
877c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy}
887c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy
897c450aaa3caac2a05fcb20a177483d0e92378426Romain Guyvoid Stencil::enableDebugWrite() {
907c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    if (mState != kWrite) {
917c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        enable();
927c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff);
937c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        // The test always passes so the first two values are meaningless
947c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
957c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
967c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy        mState = kWrite;
977c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    }
987c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy}
997c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy
1000baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::enable() {
1017c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy    if (mState == kDisabled) {
1020baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        glEnable(GL_STENCIL_TEST);
1030baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    }
1040baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
1050baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
1060baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guyvoid Stencil::disable() {
1070baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    if (mState != kDisabled) {
1080baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        glDisable(GL_STENCIL_TEST);
1090baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy        mState = kDisabled;
1100baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy    }
1110baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}
1120baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy
1130baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}; // namespace uirenderer
1140baaac5e9adf3ee280ae1239e2e58754a9d2b099Romain Guy}; // namespace android
115