| 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 | |