1/*
2Copyright (c) 2013, Broadcom Europe Ltd
3Copyright (c) 2013, Tim Gover
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 * Neither the name of the copyright holder nor the
14 names of its contributors may be used to endorse or promote products
15 derived from this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
21DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#ifndef RASPITEX_H_
30#define RASPITEX_H_
31
32#include <stdio.h>
33#include <EGL/egl.h>
34#include <EGL/eglext.h>
35#include <GLES/gl.h>
36#include <GLES/glext.h>
37#include "interface/khronos/include/EGL/eglext_brcm.h"
38#include "interface/mmal/mmal.h"
39
40#define RASPITEX_VERSION_MAJOR 1
41#define RASPITEX_VERSION_MINOR 0
42
43typedef enum
44{
45 RASPITEX_SCENE_SQUARE = 0,
46 RASPITEX_SCENE_MIRROR,
47 RASPITEX_SCENE_TEAPOT,
48 RASPITEX_SCENE_YUV,
49 RASPITEX_SCENE_SOBEL,
50 RASPITEX_SCENE_VCSM_SQUARE,
51
52} RASPITEX_SCENE_T;
53
54struct RASPITEX_STATE;
55
56typedef struct RASPITEX_SCENE_OPS
57{
58 /// Creates a native window that will be used by egl_init
59 /// to create a window surface.
60 int (*create_native_window)(struct RASPITEX_STATE *state);
61
62 /// Creates EGL surface for native window
63 int (*gl_init)(struct RASPITEX_STATE *state);
64
65 /// Updates the RGBX texture from the next MMAL buffer
66 /// Set to null if this texture type is not required
67 int (*update_texture)(struct RASPITEX_STATE *state, EGLClientBuffer mm_buf);
68
69 /// Updates the Y' plane texture from the next MMAL buffer
70 /// Set to null if this texture type is not required
71 int (*update_y_texture)(struct RASPITEX_STATE *state, EGLClientBuffer mm_buf);
72
73 /// Updates the U plane texture from the next MMAL buffer
74 /// Set to null if this texture type is not required
75 int (*update_u_texture)(struct RASPITEX_STATE *state, EGLClientBuffer mm_buf);
76
77 /// Updates the V plane texture from the next MMAL buffer
78 /// Set to null if this texture type is not required
79 int (*update_v_texture)(struct RASPITEX_STATE *state, EGLClientBuffer mm_buf);
80
81 /// Advance to the next animation step
82 int (*update_model)(struct RASPITEX_STATE *state);
83
84 /// Draw the scene - called after update_model
85 int (*redraw)(struct RASPITEX_STATE *state);
86
87 /// Allocates a buffer and copies the pixels from the current
88 /// frame-buffer into it.
89 int (*capture)(struct RASPITEX_STATE *state,
90 uint8_t **buffer, size_t *buffer_size);
91
92 /// Creates EGL surface for native window
93 void (*gl_term)(struct RASPITEX_STATE *state);
94
95 /// Destroys the native window
96 void (*destroy_native_window)(struct RASPITEX_STATE *state);
97
98 /// Called when the scene is unloaded
99 void (*close)(struct RASPITEX_STATE *state);
100} RASPITEX_SCENE_OPS;
101
102typedef struct RASPITEX_CAPTURE
103{
104 /// Wait for previous capture to complete
105 VCOS_SEMAPHORE_T start_sem;
106
107 /// Posted once the capture is complete
108 VCOS_SEMAPHORE_T completed_sem;
109
110 /// The RGB capture buffer
111 uint8_t *buffer;
112
113 /// Size of the captured buffer in bytes
114 size_t size;
115
116 /// Frame-buffer capture has been requested. Could use
117 /// a queue instead here to allow multiple capture requests.
118 int request;
119} RASPITEX_CAPTURE;
120
121/**
122 * Contains the internal state and configuration for the GL rendered
123 * preview window.
124 */
125typedef struct RASPITEX_STATE
126{
127 int version_major; /// For binary compatibility
128 int version_minor; /// Incremented for new features
129 MMAL_PORT_T *preview_port; /// Source port for preview opaque buffers
130 MMAL_POOL_T *preview_pool; /// Pool for storing opaque buffer handles
131 MMAL_QUEUE_T *preview_queue; /// Queue preview buffers to display in order
132 VCOS_THREAD_T preview_thread; /// Preview worker / GL rendering thread
133 uint32_t preview_stop; /// If zero the worker can continue
134
135 /* Copy of preview window params */
136 int32_t preview_x; /// x-offset of preview window
137 int32_t preview_y; /// y-offset of preview window
138 int32_t preview_width; /// preview y-plane width in pixels
139 int32_t preview_height; /// preview y-plane height in pixels
140
141 /* Display rectangle for the native window */
142 int32_t x; /// x-offset in pixels
143 int32_t y; /// y-offset in pixels
144 int32_t width; /// width in pixels
145 int32_t height; /// height in pixels
146 int opacity; /// Alpha value for display element
147 int gl_win_defined; /// Use rect from --glwin instead of preview
148
149 /* DispmanX info. This might be unused if a custom create_native_window
150 * does something else. */
151 DISPMANX_DISPLAY_HANDLE_T disp; /// Dispmanx display for GL preview
152 EGL_DISPMANX_WINDOW_T win; /// Dispmanx handle for preview surface
153
154 EGLNativeWindowType* native_window; /// Native window used for EGL surface
155 EGLDisplay display; /// The current EGL display
156 EGLSurface surface; /// The current EGL surface
157 EGLContext context; /// The current EGL context
158 const EGLint *egl_config_attribs; /// GL scenes preferred EGL configuration
159
160 GLuint texture; /// Name for the preview texture
161 EGLImageKHR egl_image; /// The current preview EGL image
162
163 GLuint y_texture; /// The Y plane texture
164 EGLImageKHR y_egl_image; /// EGL image for Y plane texture
165 GLuint u_texture; /// The U plane texture
166 EGLImageKHR u_egl_image; /// EGL image for U plane texture
167 GLuint v_texture; /// The V plane texture
168 EGLImageKHR v_egl_image; /// EGL image for V plane texture
169
170 MMAL_BUFFER_HEADER_T *preview_buf; /// MMAL buffer currently bound to texture(s)
171
172 RASPITEX_SCENE_T scene_id; /// Id of the scene to load
173 RASPITEX_SCENE_OPS ops; /// The interface for the current scene
174 void *scene_state; /// Pointer to scene specific data
175 int verbose; /// Log FPS
176
177 RASPITEX_CAPTURE capture; /// Frame-buffer capture state
178
179} RASPITEX_STATE;
180
181int raspitex_init(RASPITEX_STATE *state);
182void raspitex_destroy(RASPITEX_STATE *state);
183int raspitex_start(RASPITEX_STATE *state);
184void raspitex_stop(RASPITEX_STATE *state);
185void raspitex_set_defaults(RASPITEX_STATE *state);
186int raspitex_configure_preview_port(RASPITEX_STATE *state,
187 MMAL_PORT_T *preview_port);
188void raspitex_display_help();
189int raspitex_parse_cmdline(RASPITEX_STATE *state,
190 const char *arg1, const char *arg2);
191int raspitex_capture(RASPITEX_STATE *state, FILE* output_file);
192
193#endif /* RASPITEX_H_ */
194