blob: 98be04cbad16a846f321da3f645ca091654aa0c4 [file] [log] [blame]
Marius Renn65953da2012-03-27 10:44:45 -07001/*
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 <string>
18#include <vector>
19
20#include "jni/jni_shader_program.h"
21#include "jni/jni_util.h"
22
23#include "native/base/logging.h"
24#include "native/core/geometry.h"
25#include "native/core/gl_env.h"
26#include "native/core/gl_frame.h"
27#include "native/core/shader_program.h"
28#include "native/core/vertex_frame.h"
29
30using android::filterfw::GLEnv;
31using android::filterfw::GLFrame;
32using android::filterfw::Point;
33using android::filterfw::ProgramVar;
34using android::filterfw::Quad;
35using android::filterfw::ShaderProgram;
36using android::filterfw::VertexFrame;
37
38jboolean Java_android_filterfw_core_ShaderProgram_allocate(JNIEnv* env,
39 jobject thiz,
40 jobject gl_env,
41 jstring vertex_shader,
42 jstring fragment_shader) {
43 // Get the GLEnv pointer
44 GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
45
46 // Create the shader
47 if (!fragment_shader || !gl_env_ptr)
48 return false;
George Burgess IV315c9362016-11-01 16:06:39 -070049
50 std::unique_ptr<ShaderProgram> shader;
51 if (!vertex_shader)
52 shader.reset(new ShaderProgram(gl_env_ptr, ToCppString(env, fragment_shader)));
Marius Renn65953da2012-03-27 10:44:45 -070053 else
George Burgess IV315c9362016-11-01 16:06:39 -070054 shader.reset(new ShaderProgram(gl_env_ptr, ToCppString(env, vertex_shader),
55 ToCppString(env, fragment_shader)));
56 return ToJBool(WrapOwnedObjectInJava(std::move(shader), env, thiz, true));
Marius Renn65953da2012-03-27 10:44:45 -070057}
58
59jboolean Java_android_filterfw_core_ShaderProgram_deallocate(JNIEnv* env, jobject thiz) {
60 return ToJBool(DeleteNativeObject<ShaderProgram>(env, thiz));
61}
62
63jboolean Java_android_filterfw_core_ShaderProgram_compileAndLink(JNIEnv* env, jobject thiz) {
64 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
65 return program ? ToJBool(program->CompileAndLink()) : JNI_FALSE;
66}
67
68jboolean Java_android_filterfw_core_ShaderProgram_setUniformValue(JNIEnv* env,
69 jobject thiz,
70 jstring key,
71 jobject value) {
72 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
73 const Value c_value = ToCValue(env, value);
74 const std::string c_key = ToCppString(env, key);
75 if (c_value.value) {
76 return ToJBool(program && program->SetUniformValue(c_key, c_value));
77 } else {
78 ALOGE("ShaderProgram: Could not convert java object value passed for key '%s'!", c_key.c_str());
79 return JNI_FALSE;
80 }
81}
82
83jobject Java_android_filterfw_core_ShaderProgram_getUniformValue(JNIEnv* env,
84 jobject thiz,
85 jstring key) {
86 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
87 const std::string c_key = ToCppString(env, key);
88 return program ? ToJObject(env, program->GetUniformValue(c_key)) : JNI_NULL;
89}
90
91jboolean Java_android_filterfw_core_ShaderProgram_shaderProcess(JNIEnv* env,
92 jobject thiz,
93 jobjectArray inputs,
94 jobject output) {
95 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
96 std::vector<const GLFrame*> input_frames;
97 if (program && inputs && output) {
98 // Get the input frames
99 const int input_count = env->GetArrayLength(inputs);
100 for (int i = 0; i < input_count; ++i) {
101 jobject input = env->GetObjectArrayElement(inputs, i);
102 const GLFrame* input_frame = ConvertFromJava<GLFrame>(env, input);
103 if (!input || !input_frame) {
104 ALOGE("ShaderProgram: invalid input frame %d!", i);
105 return JNI_FALSE;
106 }
107 input_frames.push_back(input_frame);
108 }
109
110 // Get the output frame
111 GLFrame* output_frame = ConvertFromJava<GLFrame>(env, output);
112 if (!output_frame) {
113 ALOGE("ShaderProgram: no output frame found!");
114 return JNI_FALSE;
115 }
116
117 // Process the frames!
118 if (!program->Process(input_frames, output_frame)) {
119 ALOGE("ShaderProgram: error processing shader!");
120 return JNI_FALSE;
121 }
122
123 return JNI_TRUE;
124 }
125 return JNI_FALSE;
126}
127
128jobject Java_android_filterfw_core_ShaderProgram_nativeCreateIdentity(JNIEnv* env,
129 jclass,
130 jobject gl_env) {
131 GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
132 ShaderProgram* program = gl_env_ptr ? ShaderProgram::CreateIdentity(gl_env_ptr) : NULL;
133 return program ? WrapNewObjectInJava(program, env, false) : NULL;
134}
135
136jboolean Java_android_filterfw_core_ShaderProgram_setSourceRegion(JNIEnv* env,
137 jobject thiz,
138 jfloat x0,
139 jfloat y0,
140 jfloat x1,
141 jfloat y1,
142 jfloat x2,
143 jfloat y2,
144 jfloat x3,
145 jfloat y3) {
146 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
147 if (program) {
148 program->SetSourceRegion(Quad(Point(x0, y0), Point(x1, y1), Point(x2, y2), Point(x3, y3)));
149 return JNI_TRUE;
150 }
151 return JNI_FALSE;
152}
153
154jboolean Java_android_filterfw_core_ShaderProgram_setTargetRegion(JNIEnv* env,
155 jobject thiz,
156 jfloat x0,
157 jfloat y0,
158 jfloat x1,
159 jfloat y1,
160 jfloat x2,
161 jfloat y2,
162 jfloat x3,
163 jfloat y3) {
164 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
165 if (program) {
166 program->SetTargetRegion(Quad(Point(x0, y0), Point(x1, y1), Point(x2, y2), Point(x3, y3)));
167 return JNI_TRUE;
168 }
169 return JNI_FALSE;
170}
171
172jboolean Java_android_filterfw_core_ShaderProgram_setShaderClearsOutput(JNIEnv* env,
173 jobject thiz,
174 jboolean clears) {
175 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
176 if (program) {
177 program->SetClearsOutput(ToCppBool(clears));
178 return JNI_TRUE;
179 }
180 return JNI_FALSE;
181}
182
183jboolean Java_android_filterfw_core_ShaderProgram_setShaderBlendEnabled(JNIEnv* env,
184 jobject thiz,
185 jboolean enable) {
186 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
187 if (program) {
188 program->SetBlendEnabled(ToCppBool(enable));
189 return JNI_TRUE;
190 }
191 return JNI_FALSE;
192}
193
194jboolean Java_android_filterfw_core_ShaderProgram_setShaderBlendFunc(JNIEnv* env,
195 jobject thiz,
196 jint sfactor,
197 jint dfactor) {
198 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
199 if (program) {
200 program->SetBlendFunc(sfactor, dfactor);
201 return JNI_TRUE;
202 }
203 return JNI_FALSE;
204}
205
206jboolean Java_android_filterfw_core_ShaderProgram_setShaderClearColor(JNIEnv* env,
207 jobject thiz,
208 jfloat r,
209 jfloat g,
210 jfloat b) {
211 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
212 if (program) {
213 program->SetClearColor(r, g, b, 1.0f);
214 return JNI_TRUE;
215 }
216 return JNI_FALSE;
217}
218
219jboolean Java_android_filterfw_core_ShaderProgram_setShaderDrawMode(JNIEnv* env,
220 jobject thiz,
221 jint draw_mode) {
222 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
223 if (program) {
224 program->SetDrawMode(draw_mode);
225 return JNI_TRUE;
226 }
227 return JNI_FALSE;
228}
229
230jboolean Java_android_filterfw_core_ShaderProgram_setShaderTileCounts(JNIEnv* env,
231 jobject thiz,
232 jint x_count,
233 jint y_count) {
234 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
235 if (program) {
236 program->SetTileCounts(x_count, y_count);
237 return JNI_TRUE;
238 }
239 return JNI_FALSE;
240}
241
242jboolean Java_android_filterfw_core_ShaderProgram_setShaderVertexCount(JNIEnv* env,
243 jobject thiz,
244 jint vertex_count) {
245 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
246 if (program) {
247 program->SetVertexCount(vertex_count);
248 return JNI_TRUE;
249 }
250 return JNI_FALSE;
251}
252
253jboolean Java_android_filterfw_core_ShaderProgram_beginShaderDrawing(JNIEnv* env, jobject thiz) {
254 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
255 return ToJBool(program && program->BeginDraw());
256}
257
258jboolean Java_android_filterfw_core_ShaderProgram_setShaderAttributeValues(
259 JNIEnv* env,
260 jobject thiz,
261 jstring attr_name,
262 jfloatArray values,
263 jint component_count) {
264 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
265 if (program) {
266 // Get the floats to set
267 jfloat* float_ptr = env->GetFloatArrayElements(values, NULL);
268 const int length = env->GetArrayLength(values);
269
270 // Get the program variable to set
271 const std::string attr_string = ToCppString(env, attr_name);
272 ProgramVar program_var = program->GetAttribute(attr_string);
273
274 // Set the variable
275 if (float_ptr && ShaderProgram::IsVarValid(program_var)) {
276 const bool success = program->SetAttributeValues(program_var,
277 reinterpret_cast<float*>(float_ptr),
278 length,
279 component_count);
280 env->ReleaseFloatArrayElements(values, float_ptr, JNI_ABORT);
281 return ToJBool(success);
282 }
283 }
284 return JNI_FALSE;
285}
286
287jboolean Java_android_filterfw_core_ShaderProgram_setShaderAttributeVertexFrame(
288 JNIEnv* env,
289 jobject thiz,
290 jstring attr_name,
291 jobject vertex_frame,
292 jint type,
293 jint component_count,
294 jint stride,
295 jint offset,
296 jboolean normalize) {
297 ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
298 if (program) {
299 // Get the vertex frame
300 VertexFrame* v_frame = ConvertFromJava<VertexFrame>(env, vertex_frame);
301
302 // Get the program variable to set
303 const std::string attr_string = ToCppString(env, attr_name);
304 ProgramVar program_var = program->GetAttribute(attr_string);
305
306 // Set the variable
307 if (v_frame && ShaderProgram::IsVarValid(program_var)) {
308 const bool success = program->SetAttributeValues(program_var,
309 v_frame,
310 type,
311 component_count,
312 stride,
313 offset,
314 ToCppBool(normalize));
315 return ToJBool(success);
316 }
317 }
318 return JNI_FALSE;
319}