1 | /* |
2 | Copyright (c) 2013, Broadcom Europe Ltd |
3 | Copyright (c) 2013, Tim Gover |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, 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 | |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
21 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
24 | ON 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 |
26 | SOFTWARE, 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 | |
43 | typedef 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 | |
54 | struct RASPITEX_STATE; |
55 | |
56 | typedef 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 | |
102 | typedef 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 | */ |
125 | typedef 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 | |
181 | int raspitex_init(RASPITEX_STATE *state); |
182 | void raspitex_destroy(RASPITEX_STATE *state); |
183 | int raspitex_start(RASPITEX_STATE *state); |
184 | void raspitex_stop(RASPITEX_STATE *state); |
185 | void raspitex_set_defaults(RASPITEX_STATE *state); |
186 | int raspitex_configure_preview_port(RASPITEX_STATE *state, |
187 | MMAL_PORT_T *preview_port); |
188 | void raspitex_display_help(); |
189 | int raspitex_parse_cmdline(RASPITEX_STATE *state, |
190 | const char *arg1, const char *arg2); |
191 | int raspitex_capture(RASPITEX_STATE *state, FILE* output_file); |
192 | |
193 | #endif /* RASPITEX_H_ */ |
194 | |