• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <EGL/egl.h>
21 #include <EGL/eglext.h>
22 #include <log/log.h>
23 #include <stddef.h>
24 #include <stdint.h>
25 #include <system/window.h>
26 
27 #include <atomic>
28 #include <string>
29 #include <vector>
30 
31 #include "egl_display.h"
32 
33 namespace android {
34 
35 class egl_display_t;
36 
37 class egl_object_t {
38     egl_display_t* display;
39     mutable std::atomic_size_t count;
40 
41 protected:
42     virtual ~egl_object_t();
43     virtual void terminate();
44 
45 public:
46     explicit egl_object_t(egl_display_t* display);
47     void destroy();
48 
incRef()49     inline void incRef() { count.fetch_add(1, std::memory_order_relaxed); }
decRef()50     inline size_t decRef() { return count.fetch_sub(1, std::memory_order_acq_rel); }
getDisplay()51     inline egl_display_t* getDisplay() const { return display; }
52 
53 private:
54     static bool get(egl_display_t const* display, egl_object_t* object);
55 
56 public:
57     template <typename N, typename T>
58     class LocalRef {
59         egl_object_t* ref;
60         LocalRef() = delete;
61         LocalRef(const LocalRef* rhs) = delete;
62 
63     public:
64         ~LocalRef();
65         explicit LocalRef(egl_object_t* rhs);
LocalRef(egl_display_t const * display,T o)66         explicit LocalRef(egl_display_t const* display, T o) : ref(nullptr) {
67             egl_object_t* native = reinterpret_cast<N*>(o);
68             if (o && egl_object_t::get(display, native)) {
69                 ref = native;
70             }
71         }
get()72         inline N* get() { return static_cast<N*>(ref); }
73         void acquire() const;
74         void release() const;
75         void terminate();
76     };
77     template <typename N, typename T>
78     friend class LocalRef;
79 };
80 
81 template <typename N, typename T>
LocalRef(egl_object_t * rhs)82 egl_object_t::LocalRef<N, T>::LocalRef(egl_object_t* rhs) : ref(rhs) {
83     if (ref) {
84         ref->incRef();
85     }
86 }
87 
88 template <typename N, typename T>
~LocalRef()89 egl_object_t::LocalRef<N, T>::~LocalRef() {
90     if (ref) {
91         ref->destroy();
92     }
93 }
94 
95 template <typename N, typename T>
acquire()96 void egl_object_t::LocalRef<N, T>::acquire() const {
97     if (ref) {
98         ref->incRef();
99     }
100 }
101 
102 template <typename N, typename T>
release()103 void egl_object_t::LocalRef<N, T>::release() const {
104     if (ref) {
105         if (ref->decRef() == 1) {
106             // shouldn't happen because this is called from LocalRef
107             ALOGE("LocalRef::release() removed the last reference!");
108         }
109     }
110 }
111 
112 template <typename N, typename T>
terminate()113 void egl_object_t::LocalRef<N, T>::terminate() {
114     if (ref) {
115         ref->terminate();
116     }
117 }
118 
119 // ----------------------------------------------------------------------------
120 
121 class egl_surface_t : public egl_object_t {
122 protected:
123     ~egl_surface_t();
124     void terminate() override;
125 
126 public:
127     typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
128 
129     egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface,
130                   EGLint colorSpace, egl_connection_t const* cnx);
131 
getNativeWindow()132     ANativeWindow* getNativeWindow() { return win; }
getNativeWindow()133     ANativeWindow* getNativeWindow() const { return win; }
getColorSpace()134     EGLint getColorSpace() const { return colorSpace; }
135     EGLBoolean setSmpte2086Attribute(EGLint attribute, EGLint value);
136     EGLBoolean setCta8613Attribute(EGLint attribute, EGLint value);
137     EGLBoolean getColorSpaceAttribute(EGLint attribute, EGLint* value) const;
138     EGLBoolean getSmpte2086Attribute(EGLint attribute, EGLint* value) const;
139     EGLBoolean getCta8613Attribute(EGLint attribute, EGLint* value) const;
140     EGLBoolean getSmpte2086Metadata(android_smpte2086_metadata& smpte2086) const;
141     EGLBoolean getCta8613Metadata(android_cta861_3_metadata& cta861_3) const;
resetSmpte2086Metadata()142     void resetSmpte2086Metadata() { egl_smpte2086_dirty = false; }
resetCta8613Metadata()143     void resetCta8613Metadata() { egl_cta861_3_dirty = false; }
144 
145     // Try to keep the order of these fields and size unchanged. It's not public API, but
146     // it's not hard to imagine native games accessing them.
147     EGLSurface surface;
148     EGLConfig config;
149 
150 private:
151     ANativeWindow* win;
152 
153 public:
154     egl_connection_t const* cnx;
155 
156 private:
157     bool connected;
158     void disconnect();
159     EGLint colorSpace;
160 
161     struct egl_xy_color {
162         EGLint x;
163         EGLint y;
164     };
165 
166     struct egl_smpte2086_metadata {
167         struct egl_xy_color displayPrimaryRed;
168         struct egl_xy_color displayPrimaryGreen;
169         struct egl_xy_color displayPrimaryBlue;
170         struct egl_xy_color whitePoint;
171         EGLint maxLuminance;
172         EGLint minLuminance;
173     };
174 
175     struct egl_cta861_3_metadata {
176         EGLint maxContentLightLevel;
177         EGLint maxFrameAverageLightLevel;
178     };
179 
180     bool egl_smpte2086_dirty;
181     bool egl_cta861_3_dirty;
182 
183     egl_smpte2086_metadata egl_smpte2086_metadata;
184     egl_cta861_3_metadata egl_cta861_3_metadata;
185 };
186 
187 class egl_context_t : public egl_object_t {
188 protected:
~egl_context_t()189     ~egl_context_t() {}
190 
191 public:
192     typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref;
193 
194     egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config, egl_connection_t const* cnx,
195                   int version);
196 
197     void onLooseCurrent();
198     void onMakeCurrent(EGLSurface draw, EGLSurface read);
199 
200     EGLDisplay dpy;
201     EGLContext context;
202     EGLConfig config;
203     EGLSurface read;
204     EGLSurface draw;
205     egl_connection_t const* cnx;
206     int version;
207     std::string gl_extensions;
208     std::vector<std::string> tokenized_gl_extensions;
209 };
210 
211 typedef egl_surface_t::Ref SurfaceRef;
212 typedef egl_context_t::Ref ContextRef;
213 
214 template <typename NATIVE, typename EGL>
egl_to_native_cast(EGL arg)215 static inline NATIVE* egl_to_native_cast(EGL arg) {
216     return reinterpret_cast<NATIVE*>(arg);
217 }
218 
get_surface(EGLSurface surface)219 static inline egl_surface_t* get_surface(EGLSurface surface) {
220     return egl_to_native_cast<egl_surface_t>(surface);
221 }
222 
get_context(EGLContext context)223 static inline egl_context_t* get_context(EGLContext context) {
224     return egl_to_native_cast<egl_context_t>(context);
225 }
226 
227 }; // namespace android
228 
229 #endif // ANDROID_EGL_OBJECT_H
230