Home | History | Annotate | Download | only in core
      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