• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~WindowHandle()44     virtual ~WindowHandle() {
45     }
46 
47     virtual void Destroy() = 0;
48 
Equals(const WindowHandle * window)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.
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.
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.
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