Home | History | Annotate | Download | only in EGL
      1 /*
      2  ** Copyright 2007, 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_EGL_OBJECT_H
     18 #define ANDROID_EGL_OBJECT_H
     19 
     20 #include <atomic>
     21 #include <ctype.h>
     22 #include <stdint.h>
     23 #include <stdlib.h>
     24 
     25 #include <EGL/egl.h>
     26 #include <EGL/eglext.h>
     27 
     28 #include <utils/threads.h>
     29 #include <utils/String8.h>
     30 #include <utils/Vector.h>
     31 
     32 #include <system/window.h>
     33 
     34 #include "egl_display.h"
     35 
     36 // ----------------------------------------------------------------------------
     37 namespace android {
     38 // ----------------------------------------------------------------------------
     39 
     40 class egl_display_t;
     41 
     42 class egl_object_t {
     43     egl_display_t *display;
     44     mutable std::atomic_size_t count;
     45 
     46 protected:
     47     virtual ~egl_object_t();
     48     virtual void terminate();
     49 
     50 public:
     51     egl_object_t(egl_display_t* display);
     52     void destroy();
     53 
     54     inline void incRef() { count.fetch_add(1, std::memory_order_relaxed); }
     55     inline size_t decRef() { return count.fetch_sub(1, std::memory_order_acq_rel); }
     56     inline egl_display_t* getDisplay() const { return display; }
     57 
     58 private:
     59     static bool get(egl_display_t const* display, egl_object_t* object);
     60 
     61 public:
     62     template <typename N, typename T>
     63     class LocalRef {
     64         egl_object_t* ref;
     65         LocalRef();
     66         LocalRef(const LocalRef* rhs);
     67     public:
     68         ~LocalRef();
     69         explicit LocalRef(egl_object_t* rhs);
     70         explicit LocalRef(egl_display_t const* display, T o) : ref(0) {
     71             egl_object_t* native = reinterpret_cast<N*>(o);
     72             if (o && egl_object_t::get(display, native)) {
     73                 ref = native;
     74             }
     75         }
     76         inline N* get() {
     77             return static_cast<N*>(ref);
     78         }
     79         void acquire() const;
     80         void release() const;
     81         void terminate();
     82     };
     83     template <typename N, typename T>
     84     friend class LocalRef;
     85 };
     86 
     87 template<typename N, typename T>
     88 egl_object_t::LocalRef<N, T>::LocalRef(egl_object_t* rhs) : ref(rhs) {
     89     if (ref) {
     90         ref->incRef();
     91     }
     92 }
     93 
     94 template <typename N, typename T>
     95 egl_object_t::LocalRef<N,T>::~LocalRef() {
     96     if (ref) {
     97         ref->destroy();
     98     }
     99 }
    100 
    101 template <typename N, typename T>
    102 void egl_object_t::LocalRef<N,T>::acquire() const {
    103     if (ref) {
    104         ref->incRef();
    105     }
    106 }
    107 
    108 template <typename N, typename T>
    109 void egl_object_t::LocalRef<N,T>::release() const {
    110     if (ref) {
    111         if (ref->decRef() == 1) {
    112             // shouldn't happen because this is called from LocalRef
    113             ALOGE("LocalRef::release() removed the last reference!");
    114         }
    115     }
    116 }
    117 
    118 template <typename N, typename T>
    119 void egl_object_t::LocalRef<N,T>::terminate() {
    120     if (ref) {
    121         ref->terminate();
    122     }
    123 }
    124 
    125 // ----------------------------------------------------------------------------
    126 
    127 class egl_surface_t : public egl_object_t {
    128 protected:
    129     ~egl_surface_t();
    130     void terminate() override;
    131 public:
    132     typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
    133 
    134     egl_surface_t(egl_display_t* dpy, EGLConfig config,
    135             EGLNativeWindowType win, EGLSurface surface,
    136             egl_connection_t const* cnx);
    137 
    138     EGLSurface surface;
    139     EGLConfig config;
    140     sp<ANativeWindow> win;
    141     egl_connection_t const* cnx;
    142     bool enableTimestamps;
    143 private:
    144     bool connected;
    145     void disconnect();
    146 };
    147 
    148 class egl_context_t: public egl_object_t {
    149 protected:
    150     ~egl_context_t() {}
    151 public:
    152     typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref;
    153 
    154     egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
    155             egl_connection_t const* cnx, int version);
    156 
    157     void onLooseCurrent();
    158     void onMakeCurrent(EGLSurface draw, EGLSurface read);
    159 
    160     EGLDisplay dpy;
    161     EGLContext context;
    162     EGLConfig config;
    163     EGLSurface read;
    164     EGLSurface draw;
    165     egl_connection_t const* cnx;
    166     int version;
    167     String8 gl_extensions;
    168     Vector<String8> tokenized_gl_extensions;
    169 };
    170 
    171 // ----------------------------------------------------------------------------
    172 
    173 typedef egl_surface_t::Ref  SurfaceRef;
    174 typedef egl_context_t::Ref  ContextRef;
    175 
    176 // ----------------------------------------------------------------------------
    177 
    178 template<typename NATIVE, typename EGL>
    179 static inline NATIVE* egl_to_native_cast(EGL arg) {
    180     return reinterpret_cast<NATIVE*>(arg);
    181 }
    182 
    183 static inline
    184 egl_surface_t* get_surface(EGLSurface surface) {
    185     return egl_to_native_cast<egl_surface_t>(surface);
    186 }
    187 
    188 static inline
    189 egl_context_t* get_context(EGLContext context) {
    190     return egl_to_native_cast<egl_context_t>(context);
    191 }
    192 
    193 // ----------------------------------------------------------------------------
    194 }; // namespace android
    195 // ----------------------------------------------------------------------------
    196 
    197 #endif // ANDROID_EGL_OBJECT_H
    198