1 /* 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 #ifndef ANDROID_FILTERFW_CORE_GL_ENV_H 18 #define ANDROID_FILTERFW_CORE_GL_ENV_H 19 20 #include <string> 21 #include <utility> 22 #include <map> 23 24 #include "base/logging.h" 25 #include "base/utilities.h" 26 27 #include <GLES2/gl2.h> 28 #include <EGL/egl.h> 29 30 #include <utils/StrongPointer.h> 31 32 struct ANativeWindow; 33 34 namespace android { 35 36 class GLConsumer; 37 38 namespace filterfw { 39 40 class ShaderProgram; 41 class VertexFrame; 42 43 class WindowHandle { 44 public: ~WindowHandle()45 virtual ~WindowHandle() { 46 } 47 48 virtual void Destroy() = 0; 49 Equals(const WindowHandle * window)50 virtual bool Equals(const WindowHandle* window) const { 51 return InternalHandle() == window->InternalHandle(); 52 } 53 54 virtual const void* InternalHandle() const = 0; 55 56 virtual void* InternalHandle() = 0; 57 }; 58 59 // The GLEnv class provides functionality related to the EGL environment, which 60 // includes the display, context, and surface. It is possible to either create 61 // a new environment or base it off the currently active EGL environment. In 62 // order to do the latter, an EGL environment must be setup already (though not 63 // necessarily through this class), and have an active display, context, and 64 // surface. 65 class GLEnv { 66 public: 67 // Constructing and Activating ///////////////////////////////////////////// 68 // Constructs a new GLEnv object. This does not create a GL context. 69 GLEnv(); 70 71 // Destructor. Tears down and deallocates any GL objects that were created 72 // by this instance. 73 ~GLEnv(); 74 75 // Inits a new GL environment, including a new surface and context. You 76 // must call Activate() before performing any GL operations. 77 bool InitWithNewContext(); 78 79 // Inits the GL environment from the current GL environment. Use this when 80 // there is already a display, surface and context available (possibly 81 // created by the host application). You do not need to call Activate() as 82 // this context is active already. 83 bool InitWithCurrentContext(); 84 85 // Activates the environment, and makes the associated GL context the 86 // current context. Creates the environment, if it has not been created 87 // already. Returns true if the activation was successful. 88 bool Activate(); 89 90 // Deactivates the environment. Returns true if the deactivation was 91 // successful. You may want to call this when moving a context to another 92 // thread. In this case, deactivate the GLEnv in the old thread, and 93 // reactivate it in the new thread. 94 bool Deactivate(); 95 96 // When rendering to a visible surface, call this to swap between the 97 // offscreen and onscreen buffers. Returns true if the buffer swap was 98 // successful. 99 bool SwapBuffers(); 100 101 // Working with Surfaces /////////////////////////////////////////////////// 102 103 // Add a surface to the environment. This surface will now be managed (and 104 // owned) by the GLEnv instance. Returns the id of the surface. 105 int AddSurface(const EGLSurface& surface); 106 107 // Add a window surface to the environment. The window is passed in as 108 // an opaque window handle. 109 // This surface will now be managed (and owned) by the GLEnv instance. 110 // Returns the id of the surface. 111 int AddWindowSurface(const EGLSurface& surface, WindowHandle* window_handle); 112 113 // Switch to the surface with the specified id. This will make the surface 114 // active, if it is not active already. Specify an ID of 0 if you would like 115 // to switch to the default surface. Returns true if successful. 116 bool SwitchToSurfaceId(int surface_id); 117 118 // Release the surface with the specified id. This will deallocate the 119 // surface. If this is the active surface, the environment will switch to 120 // the default surface (0) first. You cannot release the default surface. 121 bool ReleaseSurfaceId(int surface_id); 122 123 // Set the timestamp for the current surface. Must be called 124 // before swapBuffers to associate the timestamp with the frame 125 // resulting from swapBuffers. 126 bool SetSurfaceTimestamp(int64_t timestamp); 127 128 // Looks for a surface with the associated window handle. Returns -1 if no 129 // surface with such a window was found. 130 int FindSurfaceIdForWindow(const WindowHandle* window_handle); 131 132 // Obtain the environment's EGL surface. surface()133 const EGLSurface& surface() const { 134 return surfaces_.find(surface_id_)->second.first; 135 } 136 137 // Working with Contexts /////////////////////////////////////////////////// 138 139 // Add a context to the environment. This context will now be managed (and 140 // owned) by the GLEnv instance. Returns the id of the context. 141 int AddContext(const EGLContext& context); 142 143 // Switch to the context with the specified id. This will make the context 144 // active, if it is not active already. Specify an ID of 0 if you would like 145 // to switch to the default context. Returns true if successful. 146 bool SwitchToContextId(int context_id); 147 148 // Release the context with the specified id. This will deallocate the 149 // context. If this is the active context, the environment will switch to 150 // the default context (0) first. You cannot release the default context. 151 void ReleaseContextId(int context_id); 152 153 // Obtain the environment's EGL context. context()154 const EGLContext& context() const { 155 return contexts_.find(context_id_)->second; 156 } 157 158 // Working with the Display //////////////////////////////////////////////// 159 160 // Obtain the environment's EGL display. display()161 const EGLDisplay& display() const { 162 return display_; 163 } 164 165 // Inspecting the environment ////////////////////////////////////////////// 166 // Returns true if the environment is active in the current thread. 167 bool IsActive() const; 168 169 // Returns true if the environment's context is active in the curent thread. 170 bool IsContextActive() const; 171 172 // Returns true if there is any EGL context active in the current thread. 173 // This need not be a context created by a GLEnv instance. 174 static bool IsAnyContextActive(); 175 176 // Attaching GL objects //////////////////////////////////////////////////// 177 178 // Attach a shader to the environment. The environment takes ownership of 179 // the shader. 180 void AttachShader(int key, ShaderProgram* shader); 181 182 // Attach a vertex frame to the environment. The environment takes ownership 183 // of the frame. 184 void AttachVertexFrame(int key, VertexFrame* frame); 185 186 // Return the shader with the specified key, or NULL if there is no such 187 // shader attached to this environment. 188 ShaderProgram* ShaderWithKey(int key); 189 190 // Return the vertex frame with the specified key, or NULL if there is no 191 // such frame attached to this environment. 192 VertexFrame* VertexFrameWithKey(int key); 193 194 // Static methods ////////////////////////////////////////////////////////// 195 // These operate on the currently active environment! 196 197 // Checks if the current environment is in a GL error state. If so, it will 198 // output an error message referencing the given operation string. Returns 199 // true if there was at least one error. 200 static bool CheckGLError(const std::string& operation); 201 202 // Checks if the current environment is in an EGL error state. If so, it 203 // will output an error message referencing the given operation string. 204 // Returns true if there was at least one error. 205 static bool CheckEGLError(const std::string& operation); 206 207 // Get the currently used (shader) program. 208 static GLuint GetCurrentProgram(); 209 210 // Get the currently active display. 211 static EGLDisplay GetCurrentDisplay(); 212 213 // Returns the number of components for a given GL type. For instance, 214 // returns 4 for vec4, and 16 for mat4. 215 static int NumberOfComponents(GLenum type); 216 217 private: 218 typedef std::pair<EGLSurface, WindowHandle*> SurfaceWindowPair; 219 220 // Initializes a new GL environment. 221 bool Init(); 222 223 // Returns true if one of the Inits has been called successfully on this 224 // instance. 225 bool IsInitialized() const; 226 227 // Outputs error messages specific to the operation eglMakeCurrent(). 228 // Returns true if there was at least one error. 229 static bool CheckEGLMakeCurrentError(); 230 231 // The EGL display, contexts, and surfaces. 232 EGLDisplay display_; 233 std::map<int, EGLContext> contexts_; 234 std::map<int, SurfaceWindowPair> surfaces_; 235 236 // The currently active context and surface ids. 237 int context_id_; 238 int surface_id_; 239 240 // Dummy surface for context 241 sp<ANativeWindow> window_; 242 243 // Dummy GLConsumer for context 244 sp<GLConsumer> surfaceTexture_; 245 246 // The maximum surface id used. 247 int max_surface_id_; 248 249 // These bools keep track of which objects this GLEnv has created (and 250 // owns). 251 bool created_context_; 252 bool created_surface_; 253 bool initialized_; 254 255 // Attachments that GL objects can add to the environment. 256 std::map<int, ShaderProgram*> attached_shaders_; 257 std::map<int, VertexFrame*> attached_vframes_; 258 259 GLEnv(const GLEnv&) = delete; 260 GLEnv& operator=(const GLEnv&) = delete; 261 }; 262 263 } // namespace filterfw 264 } // namespace android 265 266 #endif // ANDROID_FILTERFW_CORE_GL_ENV_H 267