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