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