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