1 /**
2 **
3 ** Copyright 2010, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include "src/pixelflinger2/pixelflinger2.h"
19
20 #include <string.h>
21 #include <stdio.h>
22
23 void SetShaderVerifyFunctions(GGLInterface *);
24
DepthFunc(GGLInterface * iface,GLenum func)25 static void DepthFunc(GGLInterface * iface, GLenum func)
26 {
27 GGL_GET_CONTEXT(ctx, iface);
28 if (GL_NEVER > func || GL_ALWAYS < func)
29 return gglError(GL_INVALID_ENUM);
30 ctx->state.bufferState.depthFunc = func & 0x7;
31 SetShaderVerifyFunctions(iface);
32 }
33
StencilFuncSeparate(GGLInterface * iface,GLenum face,GLenum func,GLint ref,GLuint mask)34 static void StencilFuncSeparate(GGLInterface * iface, GLenum face, GLenum func, GLint ref, GLuint mask)
35 {
36 GGL_GET_CONTEXT(ctx, iface);
37 if (GL_FRONT > face || GL_FRONT_AND_BACK < face)
38 return gglError(GL_INVALID_ENUM);
39 if (GL_NEVER > func || GL_ALWAYS < func)
40 return gglError(GL_INVALID_ENUM);
41 mask &= 0xff;
42 ref = MAX2(MIN2(ref, 0xff), 0);
43 ref &= mask;
44 if (GL_FRONT == face || GL_FRONT_AND_BACK == face) {
45 ctx->state.frontStencil.ref = ref;
46 ctx->state.frontStencil.mask = mask;
47 ctx->state.frontStencil.func = func & 0x7;
48 }
49 if (GL_BACK == face || GL_FRONT_AND_BACK == face) {
50 ctx->state.backStencil.ref = ref;
51 ctx->state.backStencil.mask = mask;
52 ctx->state.backStencil.func = func & 0x7;
53 }
54 SetShaderVerifyFunctions(iface);
55 }
56
StencilOpEnum(GLenum func,unsigned oldValue)57 static unsigned StencilOpEnum(GLenum func, unsigned oldValue)
58 {
59 switch (func) {
60 case GL_ZERO:
61 return 0;
62 case GL_KEEP: // fall through
63 case GL_REPLACE: // fall through
64 case GL_INCR: // fall through
65 case GL_DECR:
66 return func - GL_KEEP + 1;
67 break;
68 case GL_INVERT:
69 return 5;
70 case GL_INCR_WRAP:
71 return 6;
72 case GL_DECR_WRAP:
73 return 7;
74 default:
75 gglError(GL_INVALID_ENUM);
76 return oldValue;
77 }
78 }
79
StencilOpSeparate(GGLInterface * iface,GLenum face,GLenum sfail,GLenum dpfail,GLenum dppass)80 static void StencilOpSeparate(GGLInterface * iface, GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)
81 {
82 GGL_GET_CONTEXT(ctx, iface);
83 if (GL_FRONT > face || GL_FRONT_AND_BACK < face)
84 return gglError(GL_INVALID_ENUM);
85 if (GL_FRONT == face || GL_FRONT_AND_BACK == face) {
86 ctx->state.frontStencil.sFail = StencilOpEnum(sfail, ctx->state.frontStencil.sFail);
87 ctx->state.frontStencil.dFail = StencilOpEnum(dpfail, ctx->state.frontStencil.dFail);
88 ctx->state.frontStencil.dPass = StencilOpEnum(dppass, ctx->state.frontStencil.dPass);
89 }
90 if (GL_BACK == face || GL_FRONT_AND_BACK == face) {
91 ctx->state.backStencil.sFail = StencilOpEnum(sfail, ctx->state.backStencil.sFail);
92 ctx->state.backStencil.dFail = StencilOpEnum(dpfail, ctx->state.backStencil.dFail);
93 ctx->state.backStencil.dPass = StencilOpEnum(dppass, ctx->state.backStencil.dPass);
94 }
95 SetShaderVerifyFunctions(iface);
96 }
97
StencilSelect(const GGLInterface * iface,GLenum face)98 static void StencilSelect(const GGLInterface * iface, GLenum face)
99 {
100 GGL_GET_CONTEXT(ctx, iface);
101 if (GL_FRONT == face) {
102 ctx->activeStencil.face = 0;
103 ctx->activeStencil.ref = ctx->state.frontStencil.ref;
104 ctx->activeStencil.mask = ctx->state.frontStencil.mask;
105 } else if (GL_BACK == face) {
106 ctx->activeStencil.face = 1;
107 ctx->activeStencil.ref = ctx->state.backStencil.ref;
108 ctx->activeStencil.mask = ctx->state.backStencil.mask;
109 }
110 }
111
ClearStencil(GGLInterface * iface,GLint s)112 static void ClearStencil(GGLInterface * iface, GLint s)
113 {
114 GGL_GET_CONTEXT(ctx, iface);
115 ctx->clearState.stencil = 0x01010101 * ((unsigned &)s & 0xff);
116 }
117
ClearColor(GGLInterface * iface,GLclampf r,GLclampf g,GLclampf b,GLclampf a)118 static void ClearColor(GGLInterface * iface, GLclampf r, GLclampf g, GLclampf b, GLclampf a)
119 {
120 GGL_GET_CONTEXT(ctx, iface);
121 r = MAX2(MIN2(r, 1.0f), 0);
122 g = MAX2(MIN2(g, 1.0f), 0);
123 b = MAX2(MIN2(b, 1.0f), 0);
124 a = MAX2(MIN2(a, 1.0f), 0);
125 ctx->clearState.color = (unsigned(a * 255) << 24) | (unsigned(b * 255) << 16) |
126 (unsigned(g * 255) << 8) | unsigned(r * 255);
127 }
128
ClearDepthf(GGLInterface * iface,GLclampf d)129 static void ClearDepthf(GGLInterface * iface, GLclampf d)
130 {
131 GGL_GET_CONTEXT(ctx, iface);
132 // assuming ieee 754 32 bit float and 32 bit 2's complement int
133 assert(sizeof(d) == sizeof(ctx->clearState.depth));
134 ctx->clearState.depth = (int &)d; // bit reinterpretation
135 if (0x80000000 & ctx->clearState.depth) // smaller negative float has bigger int representation, so flip
136 ctx->clearState.depth ^= 0x7fffffff; // since -FLT_MAX is close to -1 when bitcasted
137 }
138
Clear(const GGLInterface * iface,GLbitfield buf)139 static void Clear(const GGLInterface * iface, GLbitfield buf)
140 {
141 GGL_GET_CONST_CONTEXT(ctx, iface);
142
143 // TODO DXL scissor test
144 if (GL_COLOR_BUFFER_BIT & buf && ctx->frameSurface.data) {
145 if (GGL_PIXEL_FORMAT_RGBA_8888 == ctx->frameSurface.format) {
146 unsigned * const end = (unsigned *)ctx->frameSurface.data +
147 ctx->frameSurface.width * ctx->frameSurface.height;
148 const unsigned color = ctx->clearState.color;
149 for (unsigned * start = (unsigned *)ctx->frameSurface.data; start < end; start++)
150 *start = color;
151 } else if (GGL_PIXEL_FORMAT_RGB_565 == ctx->frameSurface.format) {
152 short * const end = (short *)ctx->frameSurface.data +
153 ctx->frameSurface.width * ctx->frameSurface.height;
154 unsigned r = ctx->clearState.color & 0xf8, g = ctx->clearState.color & 0xfc00,
155 b = ctx->clearState.color & 0xf80000;
156 const short color = (b >> 19) | (g >> 5) | (r >> 3);
157 for (short * start = (short *)ctx->frameSurface.data; start < end; start++)
158 *start = color;
159 } else
160 assert(0);
161 }
162 if (GL_DEPTH_BUFFER_BIT & buf && ctx->depthSurface.data) {
163 assert(GGL_PIXEL_FORMAT_Z_32 == ctx->depthSurface.format);
164 unsigned * const end = (unsigned *)ctx->depthSurface.data +
165 ctx->depthSurface.width * ctx->depthSurface.height;
166 const unsigned depth = ctx->clearState.depth;
167 for (unsigned * start = (unsigned *)ctx->depthSurface.data; start < end; start++)
168 *start = depth;
169 }
170 if (GL_STENCIL_BUFFER_BIT & buf && ctx->stencilSurface.data) {
171 assert(GGL_PIXEL_FORMAT_S_8 == ctx->stencilSurface.format);
172 unsigned * const end = (unsigned *)((unsigned char *)ctx->stencilSurface.data +
173 ctx->stencilSurface.width * ctx->stencilSurface.height);
174 unsigned * start = (unsigned *)ctx->stencilSurface.data;
175 const unsigned stencil = ctx->clearState.stencil;
176 for (start; start < end; start++)
177 *start = stencil;
178 start--;
179 for (unsigned char * i = (unsigned char *)start; i < (unsigned char *)end; i++)
180 *i = stencil & 0xff;
181 }
182 }
183
SetBuffer(GGLInterface * iface,const GLenum type,GGLSurface * surface)184 static void SetBuffer(GGLInterface * iface, const GLenum type, GGLSurface * surface)
185 {
186 GGL_GET_CONTEXT(ctx, iface);
187 bool changed = false;
188 if (GL_COLOR_BUFFER_BIT == type) {
189 if (surface) {
190 ctx->frameSurface = *surface;
191 changed |= ctx->frameSurface.format ^ surface->format;
192 switch (surface->format) {
193 case GGL_PIXEL_FORMAT_RGBA_8888:
194 case GGL_PIXEL_FORMAT_RGB_565:
195 break;
196 case GGL_PIXEL_FORMAT_RGBX_8888:
197 default:
198 ALOGD("pf2: SetBuffer 0x%.04X format=0x%.02X \n", type, surface ? surface->format : 0);
199 assert(0);
200 }
201 } else {
202 memset(&ctx->frameSurface, 0, sizeof(ctx->frameSurface));
203 changed = true;
204 }
205 ctx->state.bufferState.colorFormat = ctx->frameSurface.format;
206 } else if (GL_DEPTH_BUFFER_BIT == type) {
207 if (surface) {
208 ctx->depthSurface = *surface;
209 changed |= ctx->depthSurface.format ^ surface->format;
210 assert(GGL_PIXEL_FORMAT_Z_32 == ctx->depthSurface.format);
211 } else {
212 memset(&ctx->depthSurface, 0, sizeof(ctx->depthSurface));
213 changed = true;
214 }
215 ctx->state.bufferState.depthFormat = ctx->depthSurface.format;
216 } else if (GL_STENCIL_BUFFER_BIT == type) {
217 if (surface) {
218 ctx->stencilSurface = *surface;
219 changed |= ctx->stencilSurface.format ^ surface->format;
220 assert(GGL_PIXEL_FORMAT_S_8 == ctx->stencilSurface.format);
221 } else {
222 memset(&ctx->stencilSurface, 0, sizeof(ctx->stencilSurface));
223 changed = true;
224 }
225 ctx->state.bufferState.stencilFormat = ctx->stencilSurface.format;
226 } else
227 gglError(GL_INVALID_ENUM);
228 if (changed) {
229 SetShaderVerifyFunctions(iface);
230 }
231 }
232
InitializeBufferFunctions(GGLInterface * iface)233 void InitializeBufferFunctions(GGLInterface * iface)
234 {
235 iface->DepthFunc = DepthFunc;
236 iface->StencilFuncSeparate = StencilFuncSeparate;
237 iface->StencilOpSeparate = StencilOpSeparate;
238 iface->StencilSelect = StencilSelect;
239 iface->ClearStencil = ClearStencil;
240 iface->ClearColor = ClearColor;
241 iface->ClearDepthf = ClearDepthf;
242 iface->Clear = Clear;
243 iface->SetBuffer = SetBuffer;
244 }
245