/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_FILTERFW_CORE_GL_ENV_H #define ANDROID_FILTERFW_CORE_GL_ENV_H #include #include #include #include "base/logging.h" #include "base/utilities.h" #include #include #include #include namespace android { class GLConsumer; namespace filterfw { class ShaderProgram; class VertexFrame; class WindowHandle { public: virtual ~WindowHandle() { } virtual void Destroy() = 0; virtual bool Equals(const WindowHandle* window) const { return InternalHandle() == window->InternalHandle(); } virtual const void* InternalHandle() const = 0; virtual void* InternalHandle() = 0; }; // The GLEnv class provides functionality related to the EGL environment, which // includes the display, context, and surface. It is possible to either create // a new environment or base it off the currently active EGL environment. In // order to do the latter, an EGL environment must be setup already (though not // necessarily through this class), and have an active display, context, and // surface. class GLEnv { public: // Constructing and Activating ///////////////////////////////////////////// // Constructs a new GLEnv object. This does not create a GL context. GLEnv(); // Destructor. Tears down and deallocates any GL objects that were created // by this instance. ~GLEnv(); // Inits a new GL environment, including a new surface and context. You // must call Activate() before performing any GL operations. bool InitWithNewContext(); // Inits the GL environment from the current GL environment. Use this when // there is already a display, surface and context available (possibly // created by the host application). You do not need to call Activate() as // this context is active already. bool InitWithCurrentContext(); // Activates the environment, and makes the associated GL context the // current context. Creates the environment, if it has not been created // already. Returns true if the activation was successful. bool Activate(); // Deactivates the environment. Returns true if the deactivation was // successful. You may want to call this when moving a context to another // thread. In this case, deactivate the GLEnv in the old thread, and // reactivate it in the new thread. bool Deactivate(); // When rendering to a visible surface, call this to swap between the // offscreen and onscreen buffers. Returns true if the buffer swap was // successful. bool SwapBuffers(); // Working with Surfaces /////////////////////////////////////////////////// // Add a surface to the environment. This surface will now be managed (and // owned) by the GLEnv instance. Returns the id of the surface. int AddSurface(const EGLSurface& surface); // Add a window surface to the environment. The window is passed in as // an opaque window handle. // This surface will now be managed (and owned) by the GLEnv instance. // Returns the id of the surface. int AddWindowSurface(const EGLSurface& surface, WindowHandle* window_handle); // Switch to the surface with the specified id. This will make the surface // active, if it is not active already. Specify an ID of 0 if you would like // to switch to the default surface. Returns true if successful. bool SwitchToSurfaceId(int surface_id); // Release the surface with the specified id. This will deallocate the // surface. If this is the active surface, the environment will switch to // the default surface (0) first. You cannot release the default surface. bool ReleaseSurfaceId(int surface_id); // Set the timestamp for the current surface. Must be called // before swapBuffers to associate the timestamp with the frame // resulting from swapBuffers. bool SetSurfaceTimestamp(int64_t timestamp); // Looks for a surface with the associated window handle. Returns -1 if no // surface with such a window was found. int FindSurfaceIdForWindow(const WindowHandle* window_handle); // Obtain the environment's EGL surface. const EGLSurface& surface() const { return surfaces_.find(surface_id_)->second.first; } // Working with Contexts /////////////////////////////////////////////////// // Add a context to the environment. This context will now be managed (and // owned) by the GLEnv instance. Returns the id of the context. int AddContext(const EGLContext& context); // Switch to the context with the specified id. This will make the context // active, if it is not active already. Specify an ID of 0 if you would like // to switch to the default context. Returns true if successful. bool SwitchToContextId(int context_id); // Release the context with the specified id. This will deallocate the // context. If this is the active context, the environment will switch to // the default context (0) first. You cannot release the default context. void ReleaseContextId(int context_id); // Obtain the environment's EGL context. const EGLContext& context() const { return contexts_.find(context_id_)->second; } // Working with the Display //////////////////////////////////////////////// // Obtain the environment's EGL display. const EGLDisplay& display() const { return display_; } // Inspecting the environment ////////////////////////////////////////////// // Returns true if the environment is active in the current thread. bool IsActive() const; // Returns true if the environment's context is active in the curent thread. bool IsContextActive() const; // Returns true if there is any EGL context active in the current thread. // This need not be a context created by a GLEnv instance. static bool IsAnyContextActive(); // Attaching GL objects //////////////////////////////////////////////////// // Attach a shader to the environment. The environment takes ownership of // the shader. void AttachShader(int key, ShaderProgram* shader); // Attach a vertex frame to the environment. The environment takes ownership // of the frame. void AttachVertexFrame(int key, VertexFrame* frame); // Return the shader with the specified key, or NULL if there is no such // shader attached to this environment. ShaderProgram* ShaderWithKey(int key); // Return the vertex frame with the specified key, or NULL if there is no // such frame attached to this environment. VertexFrame* VertexFrameWithKey(int key); // Static methods ////////////////////////////////////////////////////////// // These operate on the currently active environment! // Checks if the current environment is in a GL error state. If so, it will // output an error message referencing the given operation string. Returns // true if there was at least one error. static bool CheckGLError(const std::string& operation); // Checks if the current environment is in an EGL error state. If so, it // will output an error message referencing the given operation string. // Returns true if there was at least one error. static bool CheckEGLError(const std::string& operation); // Get the currently used (shader) program. static GLuint GetCurrentProgram(); // Get the currently active display. static EGLDisplay GetCurrentDisplay(); // Returns the number of components for a given GL type. For instance, // returns 4 for vec4, and 16 for mat4. static int NumberOfComponents(GLenum type); private: typedef std::pair SurfaceWindowPair; // Initializes a new GL environment. bool Init(); // Returns true if one of the Inits has been called successfully on this // instance. bool IsInitialized() const; // Outputs error messages specific to the operation eglMakeCurrent(). // Returns true if there was at least one error. static bool CheckEGLMakeCurrentError(); // The EGL display, contexts, and surfaces. EGLDisplay display_; std::map contexts_; std::map surfaces_; // The currently active context and surface ids. int context_id_; int surface_id_; // Dummy surface for context sp window_; // Dummy GLConsumer for context sp surfaceTexture_; // The maximum surface id used. int max_surface_id_; // These bools keep track of which objects this GLEnv has created (and // owns). bool created_context_; bool created_surface_; bool initialized_; // Attachments that GL objects can add to the environment. std::map attached_shaders_; std::map attached_vframes_; DISALLOW_COPY_AND_ASSIGN(GLEnv); }; } // namespace filterfw } // namespace android #endif // ANDROID_FILTERFW_CORE_GL_ENV_H