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