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