2 * Copyright (C) 2013 Canonical Ltd
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com>
20 #include <hybris/camera/camera_compatibility_layer.h>
21 #include <hybris/camera/camera_compatibility_layer_capabilities.h>
23 #include <hybris/input/input_stack_compatibility_layer.h>
24 #include <hybris/input/input_stack_compatibility_layer_codes_key.h>
25 #include <hybris/input/input_stack_compatibility_layer_flags_key.h>
26 #include <hybris/input/input_stack_compatibility_layer_flags_motion.h>
28 #include <hybris/surface_flinger/surface_flinger_compatibility_layer.h>
30 #include <gui/ISurfaceComposer.h>
32 #include <GLES2/gl2.h>
33 #include <GLES2/gl2ext.h>
36 #include <sys/types.h>
46 int32_t current_zoom_level
= 1;
47 bool new_camera_frame_available
= true;
49 EffectMode
next_effect()
51 static EffectMode current_effect
= EFFECT_MODE_NONE
;
53 EffectMode next
= current_effect
;
55 switch (current_effect
) {
56 case EFFECT_MODE_NONE
:
57 next
= EFFECT_MODE_MONO
;
59 case EFFECT_MODE_MONO
:
60 next
= EFFECT_MODE_NEGATIVE
;
62 case EFFECT_MODE_NEGATIVE
:
63 next
= EFFECT_MODE_SOLARIZE
;
65 case EFFECT_MODE_SOLARIZE
:
66 next
= EFFECT_MODE_SEPIA
;
68 case EFFECT_MODE_SEPIA
:
69 next
= EFFECT_MODE_POSTERIZE
;
71 case EFFECT_MODE_POSTERIZE
:
72 next
= EFFECT_MODE_WHITEBOARD
;
74 case EFFECT_MODE_WHITEBOARD
:
75 next
= EFFECT_MODE_BLACKBOARD
;
77 case EFFECT_MODE_BLACKBOARD
:
78 next
= EFFECT_MODE_AQUA
;
80 case EFFECT_MODE_AQUA
:
81 next
= EFFECT_MODE_NONE
;
85 current_effect
= next
;
89 void error_msg_cb(void* context
)
91 printf("%s \n", __PRETTY_FUNCTION__
);
94 void shutter_msg_cb(void* context
)
96 printf("%s \n", __PRETTY_FUNCTION__
);
99 void zoom_msg_cb(void* context
, int32_t new_zoom_level
)
101 printf("%s \n", __PRETTY_FUNCTION__
);
103 CameraControl
* cc
= static_cast<CameraControl
*>(context
);
105 android_camera_get_current_zoom(cc
, &zoom
);
106 printf("\t Current zoom: %d\n", zoom
);
107 current_zoom_level
= new_zoom_level
;
110 void autofocus_msg_cb(void* context
)
112 printf("%s \n", __PRETTY_FUNCTION__
);
115 void raw_data_cb(void* data
, uint32_t data_size
, void* context
)
117 printf("%s: %d \n", __PRETTY_FUNCTION__
, data_size
);
120 void jpeg_data_cb(void* data
, uint32_t data_size
, void* context
)
122 printf("%s: %d \n", __PRETTY_FUNCTION__
, data_size
);
125 sprintf(fn
, "/data/shot_%d.jpeg", shot_counter
);
126 int fd
= open(fn
, O_RDWR
| O_CREAT
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
| S_IROTH
);
127 write(fd
, data
, data_size
);
131 CameraControl
* cc
= static_cast<CameraControl
*>(context
);
132 android_camera_start_preview(cc
);
135 void size_cb(void* ctx
, int width
, int height
)
137 printf("Supported size: [%d,%d]\n", width
, height
);
140 void preview_texture_needs_update_cb(void* ctx
)
142 new_camera_frame_available
= true;
145 void on_new_input_event(Event
* event
, void* context
)
149 if (event
->type
== KEY_EVENT_TYPE
&& event
->action
== ISCL_KEY_EVENT_ACTION_UP
) {
150 printf("We have got a key event: %d \n", event
->details
.key
.key_code
);
152 CameraControl
* cc
= static_cast<CameraControl
*>(context
);
154 switch(event
->details
.key
.key_code
) {
155 case ISCL_KEYCODE_VOLUME_UP
:
156 printf("\tZooming in now.\n");
157 android_camera_start_zoom(cc
, current_zoom_level
+1);
159 case ISCL_KEYCODE_VOLUME_DOWN
:
160 printf("\tZooming out now.\n");
161 android_camera_start_zoom(cc
, current_zoom_level
-1);
163 case ISCL_KEYCODE_POWER
:
164 printf("\tTaking a photo now.\n");
165 android_camera_take_snapshot(cc
);
167 case ISCL_KEYCODE_HEADSETHOOK
:
168 printf("\tSwitching effect.\n");
169 android_camera_set_effect_mode(cc
, next_effect());
171 } else if (event
->type
== MOTION_EVENT_TYPE
&&
172 event
->details
.motion
.pointer_count
== 1) {
173 if ((event
->action
& ISCL_MOTION_EVENT_ACTION_MASK
) == ISCL_MOTION_EVENT_ACTION_UP
) {
174 printf("\tMotion event(Action up): (%f, %f) \n",
175 event
->details
.motion
.pointer_coordinates
[0].x
,
176 event
->details
.motion
.pointer_coordinates
[0].y
);
179 if ((event
->action
& ISCL_MOTION_EVENT_ACTION_MASK
) == ISCL_MOTION_EVENT_ACTION_DOWN
) {
180 printf("\tMotion event(Action down): (%f, %f) \n",
181 event
->details
.motion
.pointer_coordinates
[0].x
,
182 event
->details
.motion
.pointer_coordinates
[0].y
);
187 struct ClientWithSurface
193 ClientWithSurface
client_with_surface(bool setup_surface_with_egl
)
195 ClientWithSurface cs
= ClientWithSurface();
197 cs
.client
= sf_client_create();
200 printf("Problem creating client ... aborting now.");
204 static const size_t primary_display
= 0;
206 SfSurfaceCreationParameters params
= {
209 (int) sf_get_display_width(primary_display
),
210 (int) sf_get_display_height(primary_display
),
211 -1, //PIXEL_FORMAT_RGBA_8888,
214 setup_surface_with_egl
, // Do not associate surface with egl, will be done by camera HAL
215 "CameraCompatLayerTestSurface"
218 cs
.surface
= sf_surface_create(cs
.client
, ¶ms
);
221 printf("Problem creating surface ... aborting now.");
225 sf_surface_make_current(cs
.surface
);
230 #define PRINT_GLERROR() printf("GL error@%d: %x\n", __LINE__, glGetError());
234 static const char* vertex_shader()
237 "#extension GL_OES_EGL_image_external : require \n"
238 "attribute vec4 a_position; \n"
239 "attribute vec2 a_texCoord; \n"
240 "uniform mat4 m_texMatrix; \n"
241 "varying vec2 v_texCoord; \n"
242 "varying float topDown; \n"
245 " gl_Position = a_position; \n"
246 " v_texCoord = a_texCoord; \n"
247 // " v_texCoord = (m_texMatrix * vec4(a_texCoord, 0.0, 1.0)).xy;\n"
248 //" topDown = v_texCoord.y; \n"
252 static const char* fragment_shader()
255 "#extension GL_OES_EGL_image_external : require \n"
256 "precision mediump float; \n"
257 "varying vec2 v_texCoord; \n"
258 "uniform samplerExternalOES s_texture; \n"
261 " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
265 static GLuint
loadShader(GLenum shaderType
, const char* pSource
)
267 GLuint shader
= glCreateShader(shaderType
);
270 glShaderSource(shader
, 1, &pSource
, NULL
);
271 glCompileShader(shader
);
273 glGetShaderiv(shader
, GL_COMPILE_STATUS
, &compiled
);
277 glGetShaderiv(shader
, GL_INFO_LOG_LENGTH
, &infoLen
);
279 char* buf
= (char*) malloc(infoLen
);
281 glGetShaderInfoLog(shader
, infoLen
, NULL
, buf
);
282 fprintf(stderr
, "Could not compile shader %d:\n%s\n",
286 glDeleteShader(shader
);
291 printf("Error, during shader creation: %i\n", glGetError());
297 static GLuint
create_program(const char* pVertexSource
, const char* pFragmentSource
)
299 GLuint vertexShader
= loadShader(GL_VERTEX_SHADER
, pVertexSource
);
301 printf("vertex shader not compiled\n");
305 GLuint pixelShader
= loadShader(GL_FRAGMENT_SHADER
, pFragmentSource
);
307 printf("frag shader not compiled\n");
311 GLuint program
= glCreateProgram();
313 glAttachShader(program
, vertexShader
);
314 glAttachShader(program
, pixelShader
);
315 glLinkProgram(program
);
316 GLint linkStatus
= GL_FALSE
;
317 glGetProgramiv(program
, GL_LINK_STATUS
, &linkStatus
);
319 if (linkStatus
!= GL_TRUE
) {
321 glGetProgramiv(program
, GL_INFO_LOG_LENGTH
, &bufLength
);
323 char* buf
= (char*) malloc(bufLength
);
325 glGetProgramInfoLog(program
, bufLength
, NULL
, buf
);
326 fprintf(stderr
, "Could not link program:\n%s\n", buf
);
330 glDeleteProgram(program
);
338 RenderData() : program_object(create_program(vertex_shader(), fragment_shader()))
340 position_loc
= glGetAttribLocation(program_object
, "a_position");
341 tex_coord_loc
= glGetAttribLocation(program_object
, "a_texCoord");
342 sampler_loc
= glGetUniformLocation(program_object
, "s_texture");
343 matrix_loc
= glGetUniformLocation(program_object
, "m_texMatrix");
346 // Handle to a program object
347 GLuint program_object
;
348 // Attribute locations
357 int main(int argc
, char** argv
)
359 CameraControlListener listener
;
360 memset(&listener
, 0, sizeof(listener
));
361 listener
.on_msg_error_cb
= error_msg_cb
;
362 listener
.on_msg_shutter_cb
= shutter_msg_cb
;
363 listener
.on_msg_focus_cb
= autofocus_msg_cb
;
364 listener
.on_msg_zoom_cb
= zoom_msg_cb
;
366 listener
.on_data_raw_image_cb
= raw_data_cb
;
367 listener
.on_data_compressed_image_cb
= jpeg_data_cb
;
368 listener
.on_preview_texture_needs_update_cb
= preview_texture_needs_update_cb
;
369 CameraControl
* cc
= android_camera_connect_to(FRONT_FACING_CAMERA_TYPE
,
373 printf("Problem connecting to camera");
377 listener
.context
= cc
;
379 AndroidEventListener event_listener
;
380 event_listener
.on_new_event
= on_new_input_event
;
381 event_listener
.context
= cc
;
383 InputStackConfiguration input_configuration
= { true, 25000 };
385 android_input_stack_initialize(&event_listener
, &input_configuration
);
386 android_input_stack_start();
388 android_camera_dump_parameters(cc
);
389 android_camera_enumerate_supported_picture_sizes(cc
, size_cb
, NULL
);
390 android_camera_enumerate_supported_preview_sizes(cc
, size_cb
, NULL
);
392 int min_fps
, max_fps
, current_fps
;
393 android_camera_get_preview_fps_range(cc
, &min_fps
, &max_fps
);
394 printf("Preview fps range: [%d,%d]\n", min_fps
, max_fps
);
395 android_camera_get_preview_fps(cc
, ¤t_fps
);
396 printf("Current preview fps range: %d\n", current_fps
);
398 android_camera_set_preview_size(cc
, 960, 720);
401 android_camera_get_preview_size(cc
, &width
, &height
);
402 printf("Current preview size: [%d,%d]\n", width
, height
);
403 android_camera_get_picture_size(cc
, &width
, &height
);
404 printf("Current picture size: [%d,%d]\n", width
, height
);
406 android_camera_get_current_zoom(cc
, &zoom
);
407 printf("Current zoom: %d \n", zoom
);
408 android_camera_get_max_zoom(cc
, &zoom
);
409 printf("Max zoom: %d \n", zoom
);
411 EffectMode effect_mode
;
412 FlashMode flash_mode
;
413 WhiteBalanceMode wb_mode
;
414 SceneMode scene_mode
;
415 AutoFocusMode af_mode
;
416 CameraPixelFormat pixel_format
;
417 android_camera_get_effect_mode(cc
, &effect_mode
);
418 android_camera_get_flash_mode(cc
, &flash_mode
);
419 android_camera_get_white_balance_mode(cc
, &wb_mode
);
420 android_camera_get_scene_mode(cc
, &scene_mode
);
421 android_camera_get_auto_focus_mode(cc
, &af_mode
);
422 android_camera_get_preview_format(cc
, &pixel_format
);
423 printf("Current effect mode: %d \n", effect_mode
);
424 printf("Current flash mode: %d \n", flash_mode
);
425 printf("Current wb mode: %d \n", wb_mode
);
426 printf("Current scene mode: %d \n", scene_mode
);
427 printf("Current af mode: %d \n", af_mode
);
428 printf("Current preview pixel format: %d \n", pixel_format
);
429 //android_camera_set_focus_region(cc, -200, -200, 200, 200, 300);
431 ClientWithSurface cs
= client_with_surface(true /* Associate surface with egl. */);
434 printf("Problem acquiring surface for preview");
438 EGLDisplay disp
= sf_client_get_egl_display(cs
.client
);
439 EGLSurface surface
= sf_surface_get_egl_surface(cs
.surface
);
441 RenderData render_data
;
442 GLuint preview_texture_id
;
443 glGenTextures(1, &preview_texture_id
);
444 glClearColor(1.0, 0., 0.5, 1.);
445 glTexParameteri(GL_TEXTURE_EXTERNAL_OES
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
446 glTexParameteri(GL_TEXTURE_EXTERNAL_OES
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
448 GL_TEXTURE_EXTERNAL_OES
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
450 GL_TEXTURE_EXTERNAL_OES
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
451 android_camera_set_preview_texture(cc
, preview_texture_id
);
452 android_camera_set_effect_mode(cc
, EFFECT_MODE_SEPIA
);
453 android_camera_set_flash_mode(cc
, FLASH_MODE_AUTO
);
454 android_camera_set_auto_focus_mode(cc
, AUTO_FOCUS_MODE_CONTINUOUS_PICTURE
);
455 android_camera_start_preview(cc
);
457 GLfloat transformation_matrix
[16];
458 android_camera_get_preview_texture_transformation(cc
, transformation_matrix
);
459 glUniformMatrix4fv(render_data
.matrix_loc
, 1, GL_FALSE
, transformation_matrix
);
461 printf("Started camera preview.\n");
464 /*if (new_camera_frame_available)
466 printf("Updating texture");
467 new_camera_frame_available = false;
469 static GLfloat vVertices
[] = { 0.0f
, 0.0f
, 0.0f
, // Position 0
470 0.0f
, 0.0f
, // TexCoord 0
471 0.0f
, 1.0f
, 0.0f
, // Position 1
472 0.0f
, 1.0f
, // TexCoord 1
473 1.0f
, 1.0f
, 0.0f
, // Position 2
474 1.0f
, 1.0f
, // TexCoord 2
475 1.0f
, 0.0f
, 0.0f
, // Position 3
476 1.0f
, 0.0f
// TexCoord 3
479 GLushort indices
[] = { 0, 1, 2, 0, 2, 3 };
482 // Clear the color buffer
483 glClear(GL_COLOR_BUFFER_BIT
);
484 // Use the program object
485 glUseProgram(render_data
.program_object
);
487 glEnableVertexAttribArray(render_data
.position_loc
);
488 glEnableVertexAttribArray(render_data
.tex_coord_loc
);
489 // Load the vertex position
490 glVertexAttribPointer(render_data
.position_loc
,
496 // Load the texture coordinate
497 glVertexAttribPointer(render_data
.tex_coord_loc
,
504 glActiveTexture(GL_TEXTURE0
);
505 // Set the sampler texture unit to 0
506 glUniform1i(render_data
.sampler_loc
, 0);
507 glUniform1i(render_data
.matrix_loc
, 0);
508 android_camera_update_preview_texture(cc
);
509 glDrawElements(GL_TRIANGLES
, 6, GL_UNSIGNED_SHORT
, indices
);
510 glDisableVertexAttribArray(render_data
.position_loc
);
511 glDisableVertexAttribArray(render_data
.tex_coord_loc
);
513 eglSwapBuffers(disp
, surface
);