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 "driver/rsdVertexArray.h"
26#include "driver/rsdShaderCache.h"
27#include "driver/rsdCore.h"
28
29#define GL_GLEXT_PROTOTYPES
30
31#include <GLES/gl.h>
32#include <GLES/glext.h>
33#include <GLES2/gl2.h>
34#include <GLES2/gl2ext.h>
35
36#include <time.h>
37
38namespace android {
39namespace renderscript {
40
41//////////////////////////////////////////////////////////////////////////////
42// Context
43//////////////////////////////////////////////////////////////////////////////
44
45void rsrBindTexture(Context *rsc, ProgramFragment *pf, uint32_t slot, Allocation *a) {
46    CHECK_OBJ_OR_NULL(a);
47    CHECK_OBJ(pf);
48    pf->bindTexture(rsc, slot, a);
49}
50
51void rsrBindConstant(Context *rsc, ProgramFragment *pf, uint32_t slot, Allocation *a) {
52    CHECK_OBJ_OR_NULL(a);
53    CHECK_OBJ(pf);
54    pf->bindAllocation(rsc, a, slot);
55}
56
57void rsrBindConstant(Context *rsc, ProgramVertex *pv, uint32_t slot, Allocation *a) {
58    CHECK_OBJ_OR_NULL(a);
59    CHECK_OBJ(pv);
60    pv->bindAllocation(rsc, a, slot);
61}
62
63void rsrBindSampler(Context *rsc, ProgramFragment *pf, uint32_t slot, Sampler *s) {
64    CHECK_OBJ_OR_NULL(vs);
65    CHECK_OBJ(vpf);
66    pf->bindSampler(rsc, slot, s);
67}
68
69void rsrBindProgramStore(Context *rsc, ProgramStore *ps) {
70    CHECK_OBJ_OR_NULL(ps);
71    rsc->setProgramStore(ps);
72}
73
74void rsrBindProgramFragment(Context *rsc, ProgramFragment *pf) {
75    CHECK_OBJ_OR_NULL(pf);
76    rsc->setProgramFragment(pf);
77}
78
79void rsrBindProgramVertex(Context *rsc, ProgramVertex *pv) {
80    CHECK_OBJ_OR_NULL(pv);
81    rsc->setProgramVertex(pv);
82}
83
84void rsrBindProgramRaster(Context *rsc, ProgramRaster *pr) {
85    CHECK_OBJ_OR_NULL(pr);
86    rsc->setProgramRaster(pr);
87}
88
89void rsrBindFrameBufferObjectColorTarget(Context *rsc, Allocation *a, uint32_t slot) {
90    CHECK_OBJ(va);
91    rsc->mFBOCache.bindColorTarget(rsc, a, slot);
92    rsc->mStateVertex.updateSize(rsc);
93}
94
95void rsrBindFrameBufferObjectDepthTarget(Context *rsc, Allocation *a) {
96    CHECK_OBJ(va);
97    rsc->mFBOCache.bindDepthTarget(rsc, a);
98    rsc->mStateVertex.updateSize(rsc);
99}
100
101void rsrClearFrameBufferObjectColorTarget(Context *rsc, uint32_t slot) {
102    rsc->mFBOCache.bindColorTarget(rsc, nullptr, slot);
103    rsc->mStateVertex.updateSize(rsc);
104}
105
106void rsrClearFrameBufferObjectDepthTarget(Context *rsc) {
107    rsc->mFBOCache.bindDepthTarget(rsc, nullptr);
108    rsc->mStateVertex.updateSize(rsc);
109}
110
111void rsrClearFrameBufferObjectTargets(Context *rsc) {
112    rsc->mFBOCache.resetAll(rsc);
113    rsc->mStateVertex.updateSize(rsc);
114}
115
116//////////////////////////////////////////////////////////////////////////////
117// VP
118//////////////////////////////////////////////////////////////////////////////
119
120void rsrVpLoadProjectionMatrix(Context *rsc, const rsc_Matrix *m) {
121    rsc->getProgramVertex()->setProjectionMatrix(rsc, m);
122}
123
124void rsrVpLoadModelMatrix(Context *rsc, const rsc_Matrix *m) {
125    rsc->getProgramVertex()->setModelviewMatrix(rsc, m);
126}
127
128void rsrVpLoadTextureMatrix(Context *rsc, const rsc_Matrix *m) {
129    rsc->getProgramVertex()->setTextureMatrix(rsc, m);
130}
131
132void rsrPfConstantColor(Context *rsc, ProgramFragment *pf,
133                        float r, float g, float b, float a) {
134    CHECK_OBJ(pf);
135    pf->setConstantColor(rsc, r, g, b, a);
136}
137
138void rsrVpGetProjectionMatrix(Context *rsc, rsc_Matrix *m) {
139    rsc->getProgramVertex()->getProjectionMatrix(rsc, m);
140}
141
142//////////////////////////////////////////////////////////////////////////////
143// Drawing
144//////////////////////////////////////////////////////////////////////////////
145
146
147void rsrDrawPath(Context *rsc, Path *sm) {
148    // Never shipped in a working state
149}
150
151void rsrDrawMesh(Context *rsc, Mesh *sm) {
152    CHECK_OBJ(sm);
153    if (!rsc->setupCheck()) {
154        return;
155    }
156    sm->render(rsc);
157}
158
159void rsrDrawMeshPrimitive(Context *rsc, Mesh *sm, uint32_t primIndex) {
160    CHECK_OBJ(sm);
161    if (!rsc->setupCheck()) {
162        return;
163    }
164    sm->renderPrimitive(rsc, primIndex);
165}
166
167void rsrDrawMeshPrimitiveRange(Context *rsc, Mesh *sm, uint32_t primIndex,
168                               uint32_t start, uint32_t len) {
169    CHECK_OBJ(sm);
170    if (!rsc->setupCheck()) {
171        return;
172    }
173    sm->renderPrimitiveRange(rsc, primIndex, start, len);
174}
175
176void rsrMeshComputeBoundingBox(Context *rsc, Mesh *sm,
177                               float *minX, float *minY, float *minZ,
178                               float *maxX, float *maxY, float *maxZ) {
179    CHECK_OBJ(sm);
180    sm->computeBBox(rsc);
181    *minX = sm->mBBoxMin[0];
182    *minY = sm->mBBoxMin[1];
183    *minZ = sm->mBBoxMin[2];
184    *maxX = sm->mBBoxMax[0];
185    *maxY = sm->mBBoxMax[1];
186    *maxZ = sm->mBBoxMax[2];
187}
188
189
190//////////////////////////////////////////////////////////////////////////////
191//
192//////////////////////////////////////////////////////////////////////////////
193
194
195void rsrColor(Context *rsc, float r, float g, float b, float a) {
196    ProgramFragment *pf = rsc->getProgramFragment();
197    pf->setConstantColor(rsc, r, g, b, a);
198}
199
200void rsrPrepareClear(Context *rsc) {
201    rsc->mFBOCache.setup(rsc);
202    rsc->setupProgramStore();
203}
204
205uint32_t rsrGetWidth(Context *rsc) {
206    return rsc->getWidth();
207}
208
209uint32_t rsrGetHeight(Context *rsc) {
210    return rsc->getHeight();
211}
212
213void rsrDrawTextAlloc(Context *rsc, Allocation *a, int x, int y) {
214    const char *text = (const char *)rsc->mHal.funcs.allocation.lock1D(rsc, a);
215    size_t allocSize = a->getType()->getPackedSizeBytes();
216    rsc->mStateFont.renderText(text, allocSize, x, y);
217    rsc->mHal.funcs.allocation.unlock1D(rsc, a);
218}
219
220void rsrDrawText(Context *rsc, const char *text, int x, int y) {
221    size_t textLen = strlen(text);
222    rsc->mStateFont.renderText(text, textLen, x, y);
223}
224
225static void SetMetrics(Font::Rect *metrics,
226                       int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
227    if (left) {
228        *left = metrics->left;
229    }
230    if (right) {
231        *right = metrics->right;
232    }
233    if (top) {
234        *top = metrics->top;
235    }
236    if (bottom) {
237        *bottom = metrics->bottom;
238    }
239}
240
241void rsrMeasureTextAlloc(Context *rsc, Allocation *a,
242                         int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
243    CHECK_OBJ(a);
244    const char *text = (const char *)rsc->mHal.funcs.allocation.lock1D(rsc, a);
245    size_t textLen = a->getType()->getPackedSizeBytes();
246    Font::Rect metrics;
247    rsc->mStateFont.measureText(text, textLen, &metrics);
248    SetMetrics(&metrics, left, right, top, bottom);
249    rsc->mHal.funcs.allocation.unlock1D(rsc, a);
250}
251
252void rsrMeasureText(Context *rsc, const char *text,
253                    int32_t *left, int32_t *right, int32_t *top, int32_t *bottom) {
254    size_t textLen = strlen(text);
255    Font::Rect metrics;
256    rsc->mStateFont.measureText(text, textLen, &metrics);
257    SetMetrics(&metrics, left, right, top, bottom);
258}
259
260void rsrBindFont(Context *rsc, Font *font) {
261    CHECK_OBJ(font);
262    rsi_ContextBindFont(rsc, font);
263}
264
265void rsrFontColor(Context *rsc, float r, float g, float b, float a) {
266    rsc->mStateFont.setFontColor(r, g, b, a);
267}
268
269} // namespace renderscript
270} // namespace android
271