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
150
151void rsrDrawPath(Context *rsc, Script *sc, Path *sm) {
152    CHECK_OBJ(sm);
153    if (!rsc->setupCheck()) {
154        return;
155    }
156    sm->render(rsc);
157}
158
159void rsrDrawMesh(Context *rsc, Script *sc, Mesh *sm) {
160    CHECK_OBJ(sm);
161    if (!rsc->setupCheck()) {
162        return;
163    }
164    sm->render(rsc);
165}
166
167void rsrDrawMeshPrimitive(Context *rsc, Script *sc, Mesh *sm, uint32_t primIndex) {
168    CHECK_OBJ(sm);
169    if (!rsc->setupCheck()) {
170        return;
171    }
172    sm->renderPrimitive(rsc, primIndex);
173}
174
175void rsrDrawMeshPrimitiveRange(Context *rsc, Script *sc, Mesh *sm, uint32_t primIndex,
176                               uint32_t start, uint32_t len) {
177    CHECK_OBJ(sm);
178    if (!rsc->setupCheck()) {
179        return;
180    }
181    sm->renderPrimitiveRange(rsc, primIndex, start, len);
182}
183
184void rsrMeshComputeBoundingBox(Context *rsc, Script *sc, Mesh *sm,
185                               float *minX, float *minY, float *minZ,
186                               float *maxX, float *maxY, float *maxZ) {
187    CHECK_OBJ(sm);
188    sm->computeBBox(rsc);
189    *minX = sm->mBBoxMin[0];
190    *minY = sm->mBBoxMin[1];
191    *minZ = sm->mBBoxMin[2];
192    *maxX = sm->mBBoxMax[0];
193    *maxY = sm->mBBoxMax[1];
194    *maxZ = sm->mBBoxMax[2];
195}
196
197
198//////////////////////////////////////////////////////////////////////////////
199//
200//////////////////////////////////////////////////////////////////////////////
201
202
203void rsrColor(Context *rsc, Script *sc, float r, float g, float b, float a) {
204    ProgramFragment *pf = rsc->getProgramFragment();
205    pf->setConstantColor(rsc, r, g, b, a);
206}
207
208void rsrPrepareClear(Context *rsc, Script *sc) {
209    rsc->mFBOCache.setup(rsc);
210    rsc->setupProgramStore();
211}
212
213uint32_t rsrGetWidth(Context *rsc, Script *sc) {
214    return rsc->getWidth();
215}
216
217uint32_t rsrGetHeight(Context *rsc, Script *sc) {
218    return rsc->getHeight();
219}
220
221void rsrDrawTextAlloc(Context *rsc, Script *sc, Allocation *a, int x, int y) {
222    const char *text = (const char *)rsc->mHal.funcs.allocation.lock1D(rsc, a);
223    size_t allocSize = a->getType()->getSizeBytes();
224    rsc->mStateFont.renderText(text, allocSize, x, y);
225    rsc->mHal.funcs.allocation.unlock1D(rsc, a);
226}
227
228void rsrDrawText(Context *rsc, Script *sc, const char *text, int x, int y) {
229    size_t textLen = strlen(text);
230    rsc->mStateFont.renderText(text, textLen, x, y);
231}
232
233static void SetMetrics(Font::Rect *metrics,
234                       int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
235    if (left) {
236        *left = metrics->left;
237    }
238    if (right) {
239        *right = metrics->right;
240    }
241    if (top) {
242        *top = metrics->top;
243    }
244    if (bottom) {
245        *bottom = metrics->bottom;
246    }
247}
248
249void rsrMeasureTextAlloc(Context *rsc, Script *sc, Allocation *a,
250                         int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
251    CHECK_OBJ(a);
252    const char *text = (const char *)rsc->mHal.funcs.allocation.lock1D(rsc, a);
253    size_t textLen = a->getType()->getSizeBytes();
254    Font::Rect metrics;
255    rsc->mStateFont.measureText(text, textLen, &metrics);
256    SetMetrics(&metrics, left, right, top, bottom);
257    rsc->mHal.funcs.allocation.unlock1D(rsc, a);
258}
259
260void rsrMeasureText(Context *rsc, Script *sc, const char *text,
261                    int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
262    size_t textLen = strlen(text);
263    Font::Rect metrics;
264    rsc->mStateFont.measureText(text, textLen, &metrics);
265    SetMetrics(&metrics, left, right, top, bottom);
266}
267
268void rsrBindFont(Context *rsc, Script *sc, Font *font) {
269    CHECK_OBJ(font);
270    rsi_ContextBindFont(rsc, font);
271}
272
273void rsrFontColor(Context *rsc, Script *sc, float r, float g, float b, float a) {
274    rsc->mStateFont.setFontColor(r, g, b, a);
275}
276
277}
278}
279