1/*
2 * Copyright (C) 2011 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
18#include "rsdCore.h"
19#include "rsdProgramStore.h"
20
21#include "rsContext.h"
22#include "rsProgramStore.h"
23
24#include <GLES/gl.h>
25#include <GLES/glext.h>
26
27using android::renderscript::Context;
28using android::renderscript::ProgramStore;
29
30struct DrvProgramStore {
31    GLenum blendSrc;
32    GLenum blendDst;
33    bool blendEnable;
34
35    GLenum depthFunc;
36    bool depthTestEnable;
37};
38
39bool rsdProgramStoreInit(const Context *rsc, const ProgramStore *ps) {
40    DrvProgramStore *drv = (DrvProgramStore *)calloc(1, sizeof(DrvProgramStore));
41    if (drv == nullptr) {
42        return false;
43    }
44
45    ps->mHal.drv = drv;
46    drv->depthTestEnable = true;
47
48    switch (ps->mHal.state.depthFunc) {
49    case RS_DEPTH_FUNC_ALWAYS:
50        drv->depthTestEnable = false;
51        drv->depthFunc = GL_ALWAYS;
52        break;
53    case RS_DEPTH_FUNC_LESS:
54        drv->depthFunc = GL_LESS;
55        break;
56    case RS_DEPTH_FUNC_LEQUAL:
57        drv->depthFunc = GL_LEQUAL;
58        break;
59    case RS_DEPTH_FUNC_GREATER:
60        drv->depthFunc = GL_GREATER;
61        break;
62    case RS_DEPTH_FUNC_GEQUAL:
63        drv->depthFunc = GL_GEQUAL;
64        break;
65    case RS_DEPTH_FUNC_EQUAL:
66        drv->depthFunc = GL_EQUAL;
67        break;
68    case RS_DEPTH_FUNC_NOTEQUAL:
69        drv->depthFunc = GL_NOTEQUAL;
70        break;
71    default:
72        ALOGE("Unknown depth function.");
73        goto error;
74    }
75
76
77
78    drv->blendEnable = true;
79    if ((ps->mHal.state.blendSrc == RS_BLEND_SRC_ONE) &&
80        (ps->mHal.state.blendDst == RS_BLEND_DST_ZERO)) {
81        drv->blendEnable = false;
82    }
83
84    switch (ps->mHal.state.blendSrc) {
85    case RS_BLEND_SRC_ZERO:
86        drv->blendSrc = GL_ZERO;
87        break;
88    case RS_BLEND_SRC_ONE:
89        drv->blendSrc = GL_ONE;
90        break;
91    case RS_BLEND_SRC_DST_COLOR:
92        drv->blendSrc = GL_DST_COLOR;
93        break;
94    case RS_BLEND_SRC_ONE_MINUS_DST_COLOR:
95        drv->blendSrc = GL_ONE_MINUS_DST_COLOR;
96        break;
97    case RS_BLEND_SRC_SRC_ALPHA:
98        drv->blendSrc = GL_SRC_ALPHA;
99        break;
100    case RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA:
101        drv->blendSrc = GL_ONE_MINUS_SRC_ALPHA;
102        break;
103    case RS_BLEND_SRC_DST_ALPHA:
104        drv->blendSrc = GL_DST_ALPHA;
105        break;
106    case RS_BLEND_SRC_ONE_MINUS_DST_ALPHA:
107        drv->blendSrc = GL_ONE_MINUS_DST_ALPHA;
108        break;
109    case RS_BLEND_SRC_SRC_ALPHA_SATURATE:
110        drv->blendSrc = GL_SRC_ALPHA_SATURATE;
111        break;
112    default:
113        rsc->setError(RS_ERROR_FATAL_DRIVER, "Unknown blend src mode.");
114        goto error;
115    }
116
117    switch (ps->mHal.state.blendDst) {
118    case RS_BLEND_DST_ZERO:
119        drv->blendDst = GL_ZERO;
120        break;
121    case RS_BLEND_DST_ONE:
122        drv->blendDst = GL_ONE;
123        break;
124    case RS_BLEND_DST_SRC_COLOR:
125        drv->blendDst = GL_SRC_COLOR;
126        break;
127    case RS_BLEND_DST_ONE_MINUS_SRC_COLOR:
128        drv->blendDst = GL_ONE_MINUS_SRC_COLOR;
129        break;
130    case RS_BLEND_DST_SRC_ALPHA:
131        drv->blendDst = GL_SRC_ALPHA;
132        break;
133    case RS_BLEND_DST_ONE_MINUS_SRC_ALPHA:
134        drv->blendDst = GL_ONE_MINUS_SRC_ALPHA;
135        break;
136    case RS_BLEND_DST_DST_ALPHA:
137        drv->blendDst = GL_DST_ALPHA;
138        break;
139    case RS_BLEND_DST_ONE_MINUS_DST_ALPHA:
140        drv->blendDst = GL_ONE_MINUS_DST_ALPHA;
141        break;
142    default:
143        rsc->setError(RS_ERROR_FATAL_DRIVER, "Unknown blend dst mode.");
144        goto error;
145    }
146
147    return true;
148
149error:
150    free(drv);
151    ps->mHal.drv = nullptr;
152    return false;
153}
154
155void rsdProgramStoreSetActive(const Context *rsc, const ProgramStore *ps) {
156    DrvProgramStore *drv = (DrvProgramStore *)ps->mHal.drv;
157
158    RSD_CALL_GL(glColorMask, ps->mHal.state.colorRWriteEnable,
159                ps->mHal.state.colorGWriteEnable,
160                ps->mHal.state.colorBWriteEnable,
161                ps->mHal.state.colorAWriteEnable);
162
163    if (drv->blendEnable) {
164        RSD_CALL_GL(glEnable, GL_BLEND);
165        RSD_CALL_GL(glBlendFunc, drv->blendSrc, drv->blendDst);
166    } else {
167        RSD_CALL_GL(glDisable, GL_BLEND);
168    }
169
170    if (rsc->mUserSurfaceConfig.depthMin > 0) {
171        RSD_CALL_GL(glDepthMask, ps->mHal.state.depthWriteEnable);
172        if (drv->depthTestEnable || ps->mHal.state.depthWriteEnable) {
173            RSD_CALL_GL(glEnable, GL_DEPTH_TEST);
174            RSD_CALL_GL(glDepthFunc, drv->depthFunc);
175        } else {
176            RSD_CALL_GL(glDisable, GL_DEPTH_TEST);
177        }
178    } else {
179        RSD_CALL_GL(glDepthMask, false);
180        RSD_CALL_GL(glDisable, GL_DEPTH_TEST);
181    }
182
183    /*
184    if (rsc->mUserSurfaceConfig.stencilMin > 0) {
185    } else {
186        glStencilMask(0);
187        glDisable(GL_STENCIL_TEST);
188    }
189    */
190
191    if (ps->mHal.state.ditherEnable) {
192        RSD_CALL_GL(glEnable, GL_DITHER);
193    } else {
194        RSD_CALL_GL(glDisable, GL_DITHER);
195    }
196}
197
198void rsdProgramStoreDestroy(const Context *rsc, const ProgramStore *ps) {
199    free(ps->mHal.drv);
200    ps->mHal.drv = nullptr;
201}
202
203
204