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