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 #include "rsContext.h"
18 #include "rsScriptC.h"
19 #include "rsMatrix4x4.h"
20 #include "rsMatrix3x3.h"
21 #include "rsMatrix2x2.h"
22 #include "rsMesh.h"
23 #include "rsgApiStructs.h"
24
25 #include "utils/Timers.h"
26 #include "driver/rsdVertexArray.h"
27 #include "driver/rsdShaderCache.h"
28 #include "driver/rsdCore.h"
29
30 #define GL_GLEXT_PROTOTYPES
31
32 #include <GLES/gl.h>
33 #include <GLES/glext.h>
34 #include <GLES2/gl2.h>
35 #include <GLES2/gl2ext.h>
36
37 #include <time.h>
38
39 using namespace android;
40 using namespace android::renderscript;
41
42 namespace android {
43 namespace renderscript {
44
45 //////////////////////////////////////////////////////////////////////////////
46 // Context
47 //////////////////////////////////////////////////////////////////////////////
48
rsrBindTexture(Context * rsc,Script * sc,ProgramFragment * pf,uint32_t slot,Allocation * a)49 void rsrBindTexture(Context *rsc, Script *sc, ProgramFragment *pf, uint32_t slot, Allocation *a) {
50 CHECK_OBJ_OR_NULL(a);
51 CHECK_OBJ(pf);
52 pf->bindTexture(rsc, slot, a);
53 }
54
rsrBindConstant(Context * rsc,Script * sc,ProgramFragment * pf,uint32_t slot,Allocation * a)55 void rsrBindConstant(Context *rsc, Script *sc, ProgramFragment *pf, uint32_t slot, Allocation *a) {
56 CHECK_OBJ_OR_NULL(a);
57 CHECK_OBJ(pf);
58 pf->bindAllocation(rsc, a, slot);
59 }
60
rsrBindConstant(Context * rsc,Script * sc,ProgramVertex * pv,uint32_t slot,Allocation * a)61 void rsrBindConstant(Context *rsc, Script *sc, ProgramVertex *pv, uint32_t slot, Allocation *a) {
62 CHECK_OBJ_OR_NULL(a);
63 CHECK_OBJ(pv);
64 pv->bindAllocation(rsc, a, slot);
65 }
66
rsrBindSampler(Context * rsc,Script * sc,ProgramFragment * pf,uint32_t slot,Sampler * s)67 void rsrBindSampler(Context *rsc, Script *sc, ProgramFragment *pf, uint32_t slot, Sampler *s) {
68 CHECK_OBJ_OR_NULL(vs);
69 CHECK_OBJ(vpf);
70 pf->bindSampler(rsc, slot, s);
71 }
72
rsrBindProgramStore(Context * rsc,Script * sc,ProgramStore * ps)73 void rsrBindProgramStore(Context *rsc, Script *sc, ProgramStore *ps) {
74 CHECK_OBJ_OR_NULL(ps);
75 rsc->setProgramStore(ps);
76 }
77
rsrBindProgramFragment(Context * rsc,Script * sc,ProgramFragment * pf)78 void rsrBindProgramFragment(Context *rsc, Script *sc, ProgramFragment *pf) {
79 CHECK_OBJ_OR_NULL(pf);
80 rsc->setProgramFragment(pf);
81 }
82
rsrBindProgramVertex(Context * rsc,Script * sc,ProgramVertex * pv)83 void rsrBindProgramVertex(Context *rsc, Script *sc, ProgramVertex *pv) {
84 CHECK_OBJ_OR_NULL(pv);
85 rsc->setProgramVertex(pv);
86 }
87
rsrBindProgramRaster(Context * rsc,Script * sc,ProgramRaster * pr)88 void rsrBindProgramRaster(Context *rsc, Script *sc, ProgramRaster *pr) {
89 CHECK_OBJ_OR_NULL(pr);
90 rsc->setProgramRaster(pr);
91 }
92
rsrBindFrameBufferObjectColorTarget(Context * rsc,Script * sc,Allocation * a,uint32_t slot)93 void rsrBindFrameBufferObjectColorTarget(Context *rsc, Script *sc, Allocation *a, uint32_t slot) {
94 CHECK_OBJ(va);
95 rsc->mFBOCache.bindColorTarget(rsc, a, slot);
96 rsc->mStateVertex.updateSize(rsc);
97 }
98
rsrBindFrameBufferObjectDepthTarget(Context * rsc,Script * sc,Allocation * a)99 void rsrBindFrameBufferObjectDepthTarget(Context *rsc, Script *sc, Allocation *a) {
100 CHECK_OBJ(va);
101 rsc->mFBOCache.bindDepthTarget(rsc, a);
102 rsc->mStateVertex.updateSize(rsc);
103 }
104
rsrClearFrameBufferObjectColorTarget(Context * rsc,Script * sc,uint32_t slot)105 void rsrClearFrameBufferObjectColorTarget(Context *rsc, Script *sc, uint32_t slot) {
106 rsc->mFBOCache.bindColorTarget(rsc, NULL, slot);
107 rsc->mStateVertex.updateSize(rsc);
108 }
109
rsrClearFrameBufferObjectDepthTarget(Context * rsc,Script * sc)110 void rsrClearFrameBufferObjectDepthTarget(Context *rsc, Script *sc) {
111 rsc->mFBOCache.bindDepthTarget(rsc, NULL);
112 rsc->mStateVertex.updateSize(rsc);
113 }
114
rsrClearFrameBufferObjectTargets(Context * rsc,Script * sc)115 void rsrClearFrameBufferObjectTargets(Context *rsc, Script *sc) {
116 rsc->mFBOCache.resetAll(rsc);
117 rsc->mStateVertex.updateSize(rsc);
118 }
119
120 //////////////////////////////////////////////////////////////////////////////
121 // VP
122 //////////////////////////////////////////////////////////////////////////////
123
rsrVpLoadProjectionMatrix(Context * rsc,Script * sc,const rsc_Matrix * m)124 void rsrVpLoadProjectionMatrix(Context *rsc, Script *sc, const rsc_Matrix *m) {
125 rsc->getProgramVertex()->setProjectionMatrix(rsc, m);
126 }
127
rsrVpLoadModelMatrix(Context * rsc,Script * sc,const rsc_Matrix * m)128 void rsrVpLoadModelMatrix(Context *rsc, Script *sc, const rsc_Matrix *m) {
129 rsc->getProgramVertex()->setModelviewMatrix(rsc, m);
130 }
131
rsrVpLoadTextureMatrix(Context * rsc,Script * sc,const rsc_Matrix * m)132 void rsrVpLoadTextureMatrix(Context *rsc, Script *sc, const rsc_Matrix *m) {
133 rsc->getProgramVertex()->setTextureMatrix(rsc, m);
134 }
135
rsrPfConstantColor(Context * rsc,Script * sc,ProgramFragment * pf,float r,float g,float b,float a)136 void rsrPfConstantColor(Context *rsc, Script *sc, ProgramFragment *pf,
137 float r, float g, float b, float a) {
138 CHECK_OBJ(pf);
139 pf->setConstantColor(rsc, r, g, b, a);
140 }
141
rsrVpGetProjectionMatrix(Context * rsc,Script * sc,rsc_Matrix * m)142 void rsrVpGetProjectionMatrix(Context *rsc, Script *sc, rsc_Matrix *m) {
143 rsc->getProgramVertex()->getProjectionMatrix(rsc, m);
144 }
145
146 //////////////////////////////////////////////////////////////////////////////
147 // Drawing
148 //////////////////////////////////////////////////////////////////////////////
149
rsrDrawQuadTexCoords(Context * rsc,Script * sc,float x1,float y1,float z1,float u1,float v1,float x2,float y2,float z2,float u2,float v2,float x3,float y3,float z3,float u3,float v3,float x4,float y4,float z4,float u4,float v4)150 void rsrDrawQuadTexCoords(Context *rsc, Script *sc,
151 float x1, float y1, float z1, float u1, float v1,
152 float x2, float y2, float z2, float u2, float v2,
153 float x3, float y3, float z3, float u3, float v3,
154 float x4, float y4, float z4, float u4, float v4) {
155 if (!rsc->setupCheck()) {
156 return;
157 }
158
159 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
160 if (!dc->gl.shaderCache->setup(rsc)) {
161 return;
162 }
163
164 //ALOGE("Quad");
165 //ALOGE("%4.2f, %4.2f, %4.2f", x1, y1, z1);
166 //ALOGE("%4.2f, %4.2f, %4.2f", x2, y2, z2);
167 //ALOGE("%4.2f, %4.2f, %4.2f", x3, y3, z3);
168 //ALOGE("%4.2f, %4.2f, %4.2f", x4, y4, z4);
169
170 float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
171 const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
172
173 RsdVertexArray::Attrib attribs[2];
174 attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position");
175 attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0");
176
177 RsdVertexArray va(attribs, 2);
178 va.setup(rsc);
179
180 RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
181 }
182
rsrDrawQuad(Context * rsc,Script * sc,float x1,float y1,float z1,float x2,float y2,float z2,float x3,float y3,float z3,float x4,float y4,float z4)183 void rsrDrawQuad(Context *rsc, Script *sc,
184 float x1, float y1, float z1,
185 float x2, float y2, float z2,
186 float x3, float y3, float z3,
187 float x4, float y4, float z4) {
188 rsrDrawQuadTexCoords(rsc, sc, x1, y1, z1, 0, 1,
189 x2, y2, z2, 1, 1,
190 x3, y3, z3, 1, 0,
191 x4, y4, z4, 0, 0);
192 }
193
rsrDrawSpriteScreenspace(Context * rsc,Script * sc,float x,float y,float z,float w,float h)194 void rsrDrawSpriteScreenspace(Context *rsc, Script *sc,
195 float x, float y, float z, float w, float h) {
196 ObjectBaseRef<const ProgramVertex> tmp(rsc->getProgramVertex());
197 rsc->setProgramVertex(rsc->getDefaultProgramVertex());
198 //rsc->setupCheck();
199
200 //GLint crop[4] = {0, h, w, -h};
201
202 float sh = rsc->getHeight();
203
204 rsrDrawQuad(rsc, sc,
205 x, sh - y, z,
206 x+w, sh - y, z,
207 x+w, sh - (y+h), z,
208 x, sh - (y+h), z);
209 rsc->setProgramVertex((ProgramVertex *)tmp.get());
210 }
211
rsrDrawRect(Context * rsc,Script * sc,float x1,float y1,float x2,float y2,float z)212 void rsrDrawRect(Context *rsc, Script *sc, float x1, float y1, float x2, float y2, float z) {
213 //ALOGE("SC_drawRect %f,%f %f,%f %f", x1, y1, x2, y2, z);
214 rsrDrawQuad(rsc, sc, x1, y2, z, x2, y2, z, x2, y1, z, x1, y1, z);
215 }
216
rsrDrawPath(Context * rsc,Script * sc,Path * sm)217 void rsrDrawPath(Context *rsc, Script *sc, Path *sm) {
218 CHECK_OBJ(sm);
219 if (!rsc->setupCheck()) {
220 return;
221 }
222 sm->render(rsc);
223 }
224
rsrDrawMesh(Context * rsc,Script * sc,Mesh * sm)225 void rsrDrawMesh(Context *rsc, Script *sc, Mesh *sm) {
226 CHECK_OBJ(sm);
227 if (!rsc->setupCheck()) {
228 return;
229 }
230 sm->render(rsc);
231 }
232
rsrDrawMeshPrimitive(Context * rsc,Script * sc,Mesh * sm,uint32_t primIndex)233 void rsrDrawMeshPrimitive(Context *rsc, Script *sc, Mesh *sm, uint32_t primIndex) {
234 CHECK_OBJ(sm);
235 if (!rsc->setupCheck()) {
236 return;
237 }
238 sm->renderPrimitive(rsc, primIndex);
239 }
240
rsrDrawMeshPrimitiveRange(Context * rsc,Script * sc,Mesh * sm,uint32_t primIndex,uint32_t start,uint32_t len)241 void rsrDrawMeshPrimitiveRange(Context *rsc, Script *sc, Mesh *sm, uint32_t primIndex,
242 uint32_t start, uint32_t len) {
243 CHECK_OBJ(sm);
244 if (!rsc->setupCheck()) {
245 return;
246 }
247 sm->renderPrimitiveRange(rsc, primIndex, start, len);
248 }
249
rsrMeshComputeBoundingBox(Context * rsc,Script * sc,Mesh * sm,float * minX,float * minY,float * minZ,float * maxX,float * maxY,float * maxZ)250 void rsrMeshComputeBoundingBox(Context *rsc, Script *sc, Mesh *sm,
251 float *minX, float *minY, float *minZ,
252 float *maxX, float *maxY, float *maxZ) {
253 CHECK_OBJ(sm);
254 sm->computeBBox();
255 *minX = sm->mBBoxMin[0];
256 *minY = sm->mBBoxMin[1];
257 *minZ = sm->mBBoxMin[2];
258 *maxX = sm->mBBoxMax[0];
259 *maxY = sm->mBBoxMax[1];
260 *maxZ = sm->mBBoxMax[2];
261 }
262
263
264 //////////////////////////////////////////////////////////////////////////////
265 //
266 //////////////////////////////////////////////////////////////////////////////
267
268
rsrColor(Context * rsc,Script * sc,float r,float g,float b,float a)269 void rsrColor(Context *rsc, Script *sc, float r, float g, float b, float a) {
270 ProgramFragment *pf = rsc->getProgramFragment();
271 pf->setConstantColor(rsc, r, g, b, a);
272 }
273
rsrPrepareClear(Context * rsc,Script * sc)274 void rsrPrepareClear(Context *rsc, Script *sc) {
275 rsc->mFBOCache.setup(rsc);
276 rsc->setupProgramStore();
277 }
278
rsrGetWidth(Context * rsc,Script * sc)279 uint32_t rsrGetWidth(Context *rsc, Script *sc) {
280 return rsc->getWidth();
281 }
282
rsrGetHeight(Context * rsc,Script * sc)283 uint32_t rsrGetHeight(Context *rsc, Script *sc) {
284 return rsc->getHeight();
285 }
286
rsrDrawTextAlloc(Context * rsc,Script * sc,Allocation * a,int x,int y)287 void rsrDrawTextAlloc(Context *rsc, Script *sc, Allocation *a, int x, int y) {
288 const char *text = (const char *)a->getPtr();
289 size_t allocSize = a->getType()->getSizeBytes();
290 rsc->mStateFont.renderText(text, allocSize, x, y);
291 }
292
rsrDrawText(Context * rsc,Script * sc,const char * text,int x,int y)293 void rsrDrawText(Context *rsc, Script *sc, const char *text, int x, int y) {
294 size_t textLen = strlen(text);
295 rsc->mStateFont.renderText(text, textLen, x, y);
296 }
297
SetMetrics(Font::Rect * metrics,int32_t * left,int32_t * right,int32_t * top,int32_t * bottom)298 static void SetMetrics(Font::Rect *metrics,
299 int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
300 if (left) {
301 *left = metrics->left;
302 }
303 if (right) {
304 *right = metrics->right;
305 }
306 if (top) {
307 *top = metrics->top;
308 }
309 if (bottom) {
310 *bottom = metrics->bottom;
311 }
312 }
313
rsrMeasureTextAlloc(Context * rsc,Script * sc,Allocation * a,int32_t * left,int32_t * right,int32_t * top,int32_t * bottom)314 void rsrMeasureTextAlloc(Context *rsc, Script *sc, Allocation *a,
315 int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
316 CHECK_OBJ(a);
317 const char *text = (const char *)a->getPtr();
318 size_t textLen = a->getType()->getSizeBytes();
319 Font::Rect metrics;
320 rsc->mStateFont.measureText(text, textLen, &metrics);
321 SetMetrics(&metrics, left, right, top, bottom);
322 }
323
rsrMeasureText(Context * rsc,Script * sc,const char * text,int32_t * left,int32_t * right,int32_t * top,int32_t * bottom)324 void rsrMeasureText(Context *rsc, Script *sc, const char *text,
325 int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
326 size_t textLen = strlen(text);
327 Font::Rect metrics;
328 rsc->mStateFont.measureText(text, textLen, &metrics);
329 SetMetrics(&metrics, left, right, top, bottom);
330 }
331
rsrBindFont(Context * rsc,Script * sc,Font * font)332 void rsrBindFont(Context *rsc, Script *sc, Font *font) {
333 CHECK_OBJ(font);
334 rsi_ContextBindFont(rsc, font);
335 }
336
rsrFontColor(Context * rsc,Script * sc,float r,float g,float b,float a)337 void rsrFontColor(Context *rsc, Script *sc, float r, float g, float b, float a) {
338 rsc->mStateFont.setFontColor(r, g, b, a);
339 }
340
341 }
342 }
343