• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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