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