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 <stdint.h>
     22 #include <stddef.h>
     23 
     24 #include <string>
     25 #include <vector>
     26 
     27 #include <EGL/egl.h>
     28 #include <EGL/eglext.h>
     29 
     30 #include <system/window.h>
     31 
     32 #include <log/log.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     explicit 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() = delete;
     66         LocalRef(const LocalRef* rhs) = delete;
     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, EGLNativeWindowType win, EGLSurface surface,
    135                   EGLint colorSpace, egl_connection_t const* cnx);
    136 
    137     ANativeWindow* getNativeWindow() { return win; }
    138     ANativeWindow* getNativeWindow() const { return win; }
    139     EGLint getColorSpace() const { return colorSpace; }
    140     EGLBoolean setSmpte2086Attribute(EGLint attribute, EGLint value);
    141     EGLBoolean setCta8613Attribute(EGLint attribute, EGLint value);
    142     EGLBoolean getColorSpaceAttribute(EGLint attribute, EGLint* value) const;
    143     EGLBoolean getSmpte2086Attribute(EGLint attribute, EGLint* value) const;
    144     EGLBoolean getCta8613Attribute(EGLint attribute, EGLint* value) const;
    145     EGLBoolean getSmpte2086Metadata(android_smpte2086_metadata& smpte2086) const;
    146     EGLBoolean getCta8613Metadata(android_cta861_3_metadata& cta861_3) const;
    147     void resetSmpte2086Metadata() { egl_smpte2086_dirty = false; }
    148     void resetCta8613Metadata() { egl_cta861_3_dirty = false; }
    149 
    150     // Try to keep the order of these fields and size unchanged. It's not public API, but
    151     // it's not hard to imagine native games accessing them.
    152     EGLSurface surface;
    153     EGLConfig config;
    154 private:
    155     ANativeWindow* win;
    156 public:
    157     egl_connection_t const* cnx;
    158 private:
    159     bool connected;
    160     void disconnect();
    161     EGLint colorSpace;
    162 
    163     struct egl_xy_color {
    164         EGLint x;
    165         EGLint y;
    166     };
    167 
    168     struct egl_smpte2086_metadata {
    169         struct egl_xy_color displayPrimaryRed;
    170         struct egl_xy_color displayPrimaryGreen;
    171         struct egl_xy_color displayPrimaryBlue;
    172         struct egl_xy_color whitePoint;
    173         EGLint maxLuminance;
    174         EGLint minLuminance;
    175     };
    176 
    177     struct egl_cta861_3_metadata {
    178         EGLint maxContentLightLevel;
    179         EGLint maxFrameAverageLightLevel;
    180     };
    181 
    182     bool egl_smpte2086_dirty;
    183     bool egl_cta861_3_dirty;
    184 
    185     egl_smpte2086_metadata egl_smpte2086_metadata;
    186     egl_cta861_3_metadata egl_cta861_3_metadata;
    187 };
    188 
    189 class egl_context_t: public egl_object_t {
    190 protected:
    191     ~egl_context_t() {}
    192 public:
    193     typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref;
    194 
    195     egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
    196             egl_connection_t const* cnx, int version);
    197 
    198     void onLooseCurrent();
    199     void onMakeCurrent(EGLSurface draw, EGLSurface read);
    200 
    201     EGLDisplay dpy;
    202     EGLContext context;
    203     EGLConfig config;
    204     EGLSurface read;
    205     EGLSurface draw;
    206     egl_connection_t const* cnx;
    207     int version;
    208     std::string gl_extensions;
    209     std::vector<std::string> tokenized_gl_extensions;
    210 };
    211 
    212 // ----------------------------------------------------------------------------
    213 
    214 typedef egl_surface_t::Ref  SurfaceRef;
    215 typedef egl_context_t::Ref  ContextRef;
    216 
    217 // ----------------------------------------------------------------------------
    218 
    219 template<typename NATIVE, typename EGL>
    220 static inline NATIVE* egl_to_native_cast(EGL arg) {
    221     return reinterpret_cast<NATIVE*>(arg);
    222 }
    223 
    224 static inline
    225 egl_surface_t* get_surface(EGLSurface surface) {
    226     return egl_to_native_cast<egl_surface_t>(surface);
    227 }
    228 
    229 static inline
    230 egl_context_t* get_context(EGLContext context) {
    231     return egl_to_native_cast<egl_context_t>(context);
    232 }
    233 
    234 // ----------------------------------------------------------------------------
    235 }; // namespace android
    236 // ----------------------------------------------------------------------------
    237 
    238 #endif // ANDROID_EGL_OBJECT_H
    239