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 
     32 #include <system/window.h>
     33 
     34 #include "egl_display.h"
     35 
     36 // ----------------------------------------------------------------------------
     37 namespace android {
     38 // ----------------------------------------------------------------------------
     39 
     40 struct egl_display_t;
     41 
     42 class egl_object_t {
     43     egl_display_t *display;
     44     mutable volatile int32_t count;
     45 
     46 protected:
     47     virtual ~egl_object_t();
     48 
     49 public:
     50     egl_object_t(egl_display_t* display);
     51     void destroy();
     52 
     53     inline int32_t incRef() { return android_atomic_inc(&count); }
     54     inline int32_t decRef() { return android_atomic_dec(&count); }
     55     inline egl_display_t* getDisplay() const { return display; }
     56 
     57 private:
     58     void terminate();
     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             LOGE("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         ANativeWindow* const window = win.get();
    131         if (window != NULL) {
    132             native_window_set_buffers_format(window, 0);
    133             if (native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL)) {
    134                 LOGW("EGLNativeWindowType %p disconnect failed", window);
    135             }
    136         }
    137     }
    138 public:
    139     typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
    140 
    141     egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win,
    142             EGLSurface surface, int impl, egl_connection_t const* cnx) :
    143         egl_object_t(get_display(dpy)), dpy(dpy), surface(surface),
    144                 config(config), win(win), impl(impl), cnx(cnx) {
    145     }
    146     EGLDisplay dpy;
    147     EGLSurface surface;
    148     EGLConfig config;
    149     sp<ANativeWindow> win;
    150     int impl;
    151     egl_connection_t const* cnx;
    152 };
    153 
    154 class egl_context_t: public egl_object_t {
    155 protected:
    156     ~egl_context_t() {}
    157 public:
    158     typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref;
    159 
    160     egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
    161             int impl, egl_connection_t const* cnx, int version) :
    162         egl_object_t(get_display(dpy)), dpy(dpy), context(context),
    163                 config(config), read(0), draw(0), impl(impl), cnx(cnx),
    164                 version(version) {
    165     }
    166     EGLDisplay dpy;
    167     EGLContext context;
    168     EGLConfig config;
    169     EGLSurface read;
    170     EGLSurface draw;
    171     int impl;
    172     egl_connection_t const* cnx;
    173     int version;
    174 };
    175 
    176 class egl_image_t: public egl_object_t {
    177 protected:
    178     ~egl_image_t() {}
    179 public:
    180     typedef egl_object_t::LocalRef<egl_image_t, EGLImageKHR> Ref;
    181 
    182     egl_image_t(EGLDisplay dpy, EGLContext context) :
    183         egl_object_t(get_display(dpy)), dpy(dpy), context(context) {
    184         memset(images, 0, sizeof(images));
    185     }
    186     EGLDisplay dpy;
    187     EGLContext context;
    188     EGLImageKHR images[IMPL_NUM_IMPLEMENTATIONS];
    189 };
    190 
    191 class egl_sync_t: public egl_object_t {
    192 protected:
    193     ~egl_sync_t() {}
    194 public:
    195     typedef egl_object_t::LocalRef<egl_sync_t, EGLSyncKHR> Ref;
    196 
    197     egl_sync_t(EGLDisplay dpy, EGLContext context, EGLSyncKHR sync) :
    198         egl_object_t(get_display(dpy)), dpy(dpy), context(context), sync(sync) {
    199     }
    200     EGLDisplay dpy;
    201     EGLContext context;
    202     EGLSyncKHR sync;
    203 };
    204 
    205 // ----------------------------------------------------------------------------
    206 
    207 typedef egl_surface_t::Ref  SurfaceRef;
    208 typedef egl_context_t::Ref  ContextRef;
    209 typedef egl_image_t::Ref    ImageRef;
    210 typedef egl_sync_t::Ref     SyncRef;
    211 
    212 // ----------------------------------------------------------------------------
    213 
    214 template<typename NATIVE, typename EGL>
    215 static inline NATIVE* egl_to_native_cast(EGL arg) {
    216     return reinterpret_cast<NATIVE*>(arg);
    217 }
    218 
    219 static inline
    220 egl_surface_t* get_surface(EGLSurface surface) {
    221     return egl_to_native_cast<egl_surface_t>(surface);
    222 }
    223 
    224 static inline
    225 egl_context_t* get_context(EGLContext context) {
    226     return egl_to_native_cast<egl_context_t>(context);
    227 }
    228 
    229 static inline
    230 egl_image_t* get_image(EGLImageKHR image) {
    231     return egl_to_native_cast<egl_image_t>(image);
    232 }
    233 
    234 static inline
    235 egl_sync_t* get_sync(EGLSyncKHR sync) {
    236     return egl_to_native_cast<egl_sync_t>(sync);
    237 }
    238 
    239 // ----------------------------------------------------------------------------
    240 }; // namespace android
    241 // ----------------------------------------------------------------------------
    242 
    243 #endif // ANDROID_EGL_OBJECT_H
    244