rsScriptC_LibGL.cpp revision e3150cfb3edb028407669e4a65e087eae77e718c
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
39using namespace android;
40using namespace android::renderscript;
41
42namespace android {
43namespace renderscript {
44
45//////////////////////////////////////////////////////////////////////////////
46// Context
47//////////////////////////////////////////////////////////////////////////////
48
49void 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
55void 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
61void 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
67void 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
73void rsrBindProgramStore(Context *rsc, Script *sc, ProgramStore *ps) {
74    CHECK_OBJ_OR_NULL(ps);
75    rsc->setProgramStore(ps);
76}
77
78void rsrBindProgramFragment(Context *rsc, Script *sc, ProgramFragment *pf) {
79    CHECK_OBJ_OR_NULL(pf);
80    rsc->setProgramFragment(pf);
81}
82
83void rsrBindProgramVertex(Context *rsc, Script *sc, ProgramVertex *pv) {
84    CHECK_OBJ_OR_NULL(pv);
85    rsc->setProgramVertex(pv);
86}
87
88void rsrBindProgramRaster(Context *rsc, Script *sc, ProgramRaster *pr) {
89    CHECK_OBJ_OR_NULL(pr);
90    rsc->setProgramRaster(pr);
91}
92
93void 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
99void rsrBindFrameBufferObjectDepthTarget(Context *rsc, Script *sc, Allocation *a) {
100    CHECK_OBJ(va);
101    rsc->mFBOCache.bindDepthTarget(rsc, a);
102    rsc->mStateVertex.updateSize(rsc);
103}
104
105void rsrClearFrameBufferObjectColorTarget(Context *rsc, Script *sc, uint32_t slot) {
106    rsc->mFBOCache.bindColorTarget(rsc, NULL, slot);
107    rsc->mStateVertex.updateSize(rsc);
108}
109
110void rsrClearFrameBufferObjectDepthTarget(Context *rsc, Script *sc) {
111    rsc->mFBOCache.bindDepthTarget(rsc, NULL);
112    rsc->mStateVertex.updateSize(rsc);
113}
114
115void rsrClearFrameBufferObjectTargets(Context *rsc, Script *sc) {
116    rsc->mFBOCache.resetAll(rsc);
117    rsc->mStateVertex.updateSize(rsc);
118}
119
120//////////////////////////////////////////////////////////////////////////////
121// VP
122//////////////////////////////////////////////////////////////////////////////
123
124void rsrVpLoadProjectionMatrix(Context *rsc, Script *sc, const rsc_Matrix *m) {
125    rsc->getProgramVertex()->setProjectionMatrix(rsc, m);
126}
127
128void rsrVpLoadModelMatrix(Context *rsc, Script *sc, const rsc_Matrix *m) {
129    rsc->getProgramVertex()->setModelviewMatrix(rsc, m);
130}
131
132void rsrVpLoadTextureMatrix(Context *rsc, Script *sc, const rsc_Matrix *m) {
133    rsc->getProgramVertex()->setTextureMatrix(rsc, m);
134}
135
136void 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
142void rsrVpGetProjectionMatrix(Context *rsc, Script *sc, rsc_Matrix *m) {
143    rsc->getProgramVertex()->getProjectionMatrix(rsc, m);
144}
145
146//////////////////////////////////////////////////////////////////////////////
147// Drawing
148//////////////////////////////////////////////////////////////////////////////
149
150void 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
183void 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
194void 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
212void 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
217void rsrDrawPath(Context *rsc, Script *sc, Path *sm) {
218    CHECK_OBJ(sm);
219    if (!rsc->setupCheck()) {
220        return;
221    }
222    sm->render(rsc);
223}
224
225void rsrDrawMesh(Context *rsc, Script *sc, Mesh *sm) {
226    CHECK_OBJ(sm);
227    if (!rsc->setupCheck()) {
228        return;
229    }
230    sm->render(rsc);
231}
232
233void 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
241void 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
250void 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(rsc);
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
269void 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
274void rsrPrepareClear(Context *rsc, Script *sc) {
275    rsc->mFBOCache.setup(rsc);
276    rsc->setupProgramStore();
277}
278
279uint32_t rsrGetWidth(Context *rsc, Script *sc) {
280    return rsc->getWidth();
281}
282
283uint32_t rsrGetHeight(Context *rsc, Script *sc) {
284    return rsc->getHeight();
285}
286
287void 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
293void 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
298static 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
314void 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
324void 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
332void rsrBindFont(Context *rsc, Script *sc, Font *font) {
333    CHECK_OBJ(font);
334    rsi_ContextBindFont(rsc, font);
335}
336
337void 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