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