• 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 #include "egl_object.h"
18 
19 #include <sstream>
20 
21 namespace android {
22 
egl_object_t(egl_display_t * disp)23 egl_object_t::egl_object_t(egl_display_t* disp) : display(disp), count(1) {
24     // NOTE: this does an implicit incRef
25     display->addObject(this);
26 }
27 
~egl_object_t()28 egl_object_t::~egl_object_t() {}
29 
terminate()30 void egl_object_t::terminate() {
31     // this marks the object as "terminated"
32     display->removeObject(this);
33     if (decRef() == 1) {
34         // shouldn't happen because this is called from LocalRef
35         ALOGE("egl_object_t::terminate() removed the last reference!");
36     }
37 }
38 
destroy()39 void egl_object_t::destroy() {
40     if (decRef() == 1) {
41         delete this;
42     }
43 }
44 
get(egl_display_t const * display,egl_object_t * object)45 bool egl_object_t::get(egl_display_t const* display, egl_object_t* object) {
46     // used by LocalRef, this does an incRef() atomically with
47     // checking that the object is valid.
48     return display->getObject(object);
49 }
50 
egl_surface_t(egl_display_t * dpy,EGLConfig config,EGLNativeWindowType win,EGLSurface surface,EGLint colorSpace,egl_connection_t const * cnx)51 egl_surface_t::egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win,
52                              EGLSurface surface, EGLint colorSpace, egl_connection_t const* cnx)
53       : egl_object_t(dpy),
54         surface(surface),
55         config(config),
56         win(win),
57         cnx(cnx),
58         connected(true),
59         colorSpace(colorSpace),
60         egl_smpte2086_dirty(false),
61         egl_cta861_3_dirty(false) {
62     egl_smpte2086_metadata.displayPrimaryRed = {EGL_DONT_CARE, EGL_DONT_CARE};
63     egl_smpte2086_metadata.displayPrimaryGreen = {EGL_DONT_CARE, EGL_DONT_CARE};
64     egl_smpte2086_metadata.displayPrimaryBlue = {EGL_DONT_CARE, EGL_DONT_CARE};
65     egl_smpte2086_metadata.whitePoint = {EGL_DONT_CARE, EGL_DONT_CARE};
66     egl_smpte2086_metadata.maxLuminance = EGL_DONT_CARE;
67     egl_smpte2086_metadata.minLuminance = EGL_DONT_CARE;
68     egl_cta861_3_metadata.maxFrameAverageLightLevel = EGL_DONT_CARE;
69     egl_cta861_3_metadata.maxContentLightLevel = EGL_DONT_CARE;
70 
71     if (win) {
72         win->incStrong(this);
73     }
74 }
75 
~egl_surface_t()76 egl_surface_t::~egl_surface_t() {
77     if (win != nullptr) {
78         disconnect();
79         win->decStrong(this);
80     }
81 }
82 
disconnect()83 void egl_surface_t::disconnect() {
84     if (win != nullptr && connected) {
85         // NOTE: When using Vulkan backend, the Vulkan runtime makes all the
86         // native_window_* calls, so don't do them here.
87         if (!cnx->angleLoaded) {
88             native_window_set_buffers_format(win, 0);
89             if (native_window_api_disconnect(win, NATIVE_WINDOW_API_EGL)) {
90                 ALOGW("EGLNativeWindowType %p disconnect failed", win);
91             }
92         }
93         connected = false;
94     }
95 }
96 
setSmpte2086Attribute(EGLint attribute,EGLint value)97 EGLBoolean egl_surface_t::setSmpte2086Attribute(EGLint attribute, EGLint value) {
98     switch (attribute) {
99         case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
100             egl_smpte2086_metadata.displayPrimaryRed.x = value;
101             egl_smpte2086_dirty = true;
102             return EGL_TRUE;
103         case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
104             egl_smpte2086_metadata.displayPrimaryRed.y = value;
105             egl_smpte2086_dirty = true;
106             return EGL_TRUE;
107         case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
108             egl_smpte2086_metadata.displayPrimaryGreen.x = value;
109             egl_smpte2086_dirty = true;
110             return EGL_TRUE;
111         case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
112             egl_smpte2086_metadata.displayPrimaryGreen.y = value;
113             egl_smpte2086_dirty = true;
114             return EGL_TRUE;
115         case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
116             egl_smpte2086_metadata.displayPrimaryBlue.x = value;
117             egl_smpte2086_dirty = true;
118             return EGL_TRUE;
119         case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
120             egl_smpte2086_metadata.displayPrimaryBlue.y = value;
121             egl_smpte2086_dirty = true;
122             return EGL_TRUE;
123         case EGL_SMPTE2086_WHITE_POINT_X_EXT:
124             egl_smpte2086_metadata.whitePoint.x = value;
125             egl_smpte2086_dirty = true;
126             return EGL_TRUE;
127         case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
128             egl_smpte2086_metadata.whitePoint.y = value;
129             egl_smpte2086_dirty = true;
130             return EGL_TRUE;
131         case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
132             egl_smpte2086_metadata.maxLuminance = value;
133             egl_smpte2086_dirty = true;
134             return EGL_TRUE;
135         case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
136             egl_smpte2086_metadata.minLuminance = value;
137             egl_smpte2086_dirty = true;
138             return EGL_TRUE;
139     }
140     return EGL_FALSE;
141 }
142 
setCta8613Attribute(EGLint attribute,EGLint value)143 EGLBoolean egl_surface_t::setCta8613Attribute(EGLint attribute, EGLint value) {
144     switch (attribute) {
145         case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
146             egl_cta861_3_metadata.maxContentLightLevel = value;
147             egl_cta861_3_dirty = true;
148             return EGL_TRUE;
149         case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
150             egl_cta861_3_metadata.maxFrameAverageLightLevel = value;
151             egl_cta861_3_dirty = true;
152             return EGL_TRUE;
153     }
154     return EGL_FALSE;
155 }
156 
getSmpte2086Metadata(android_smpte2086_metadata & metadata) const157 EGLBoolean egl_surface_t::getSmpte2086Metadata(android_smpte2086_metadata& metadata) const {
158     if (!egl_smpte2086_dirty) return EGL_FALSE;
159     if (egl_smpte2086_metadata.displayPrimaryRed.x == EGL_DONT_CARE ||
160         egl_smpte2086_metadata.displayPrimaryRed.y == EGL_DONT_CARE ||
161         egl_smpte2086_metadata.displayPrimaryGreen.x == EGL_DONT_CARE ||
162         egl_smpte2086_metadata.displayPrimaryGreen.y == EGL_DONT_CARE ||
163         egl_smpte2086_metadata.displayPrimaryBlue.x == EGL_DONT_CARE ||
164         egl_smpte2086_metadata.displayPrimaryBlue.y == EGL_DONT_CARE ||
165         egl_smpte2086_metadata.whitePoint.x == EGL_DONT_CARE ||
166         egl_smpte2086_metadata.whitePoint.y == EGL_DONT_CARE ||
167         egl_smpte2086_metadata.maxLuminance == EGL_DONT_CARE ||
168         egl_smpte2086_metadata.minLuminance == EGL_DONT_CARE) {
169         ALOGW("egl_surface_t: incomplete SMPTE 2086 metadata!");
170         return EGL_FALSE;
171     }
172 
173     metadata.displayPrimaryRed.x = static_cast<float>(egl_smpte2086_metadata.displayPrimaryRed.x) /
174             EGL_METADATA_SCALING_EXT;
175     metadata.displayPrimaryRed.y = static_cast<float>(egl_smpte2086_metadata.displayPrimaryRed.y) /
176             EGL_METADATA_SCALING_EXT;
177     metadata.displayPrimaryGreen.x =
178             static_cast<float>(egl_smpte2086_metadata.displayPrimaryGreen.x) /
179             EGL_METADATA_SCALING_EXT;
180     metadata.displayPrimaryGreen.y =
181             static_cast<float>(egl_smpte2086_metadata.displayPrimaryGreen.y) /
182             EGL_METADATA_SCALING_EXT;
183     metadata.displayPrimaryBlue.x =
184             static_cast<float>(egl_smpte2086_metadata.displayPrimaryBlue.x) /
185             EGL_METADATA_SCALING_EXT;
186     metadata.displayPrimaryBlue.y =
187             static_cast<float>(egl_smpte2086_metadata.displayPrimaryBlue.y) /
188             EGL_METADATA_SCALING_EXT;
189     metadata.whitePoint.x =
190             static_cast<float>(egl_smpte2086_metadata.whitePoint.x) / EGL_METADATA_SCALING_EXT;
191     metadata.whitePoint.y =
192             static_cast<float>(egl_smpte2086_metadata.whitePoint.y) / EGL_METADATA_SCALING_EXT;
193     metadata.maxLuminance =
194             static_cast<float>(egl_smpte2086_metadata.maxLuminance) / EGL_METADATA_SCALING_EXT;
195     metadata.minLuminance =
196             static_cast<float>(egl_smpte2086_metadata.minLuminance) / EGL_METADATA_SCALING_EXT;
197 
198     return EGL_TRUE;
199 }
200 
getCta8613Metadata(android_cta861_3_metadata & metadata) const201 EGLBoolean egl_surface_t::getCta8613Metadata(android_cta861_3_metadata& metadata) const {
202     if (!egl_cta861_3_dirty) return EGL_FALSE;
203 
204     if (egl_cta861_3_metadata.maxContentLightLevel == EGL_DONT_CARE ||
205         egl_cta861_3_metadata.maxFrameAverageLightLevel == EGL_DONT_CARE) {
206         ALOGW("egl_surface_t: incomplete CTA861.3 metadata!");
207         return EGL_FALSE;
208     }
209 
210     metadata.maxContentLightLevel = static_cast<float>(egl_cta861_3_metadata.maxContentLightLevel) /
211             EGL_METADATA_SCALING_EXT;
212     metadata.maxFrameAverageLightLevel =
213             static_cast<float>(egl_cta861_3_metadata.maxFrameAverageLightLevel) /
214             EGL_METADATA_SCALING_EXT;
215 
216     return EGL_TRUE;
217 }
218 
getColorSpaceAttribute(EGLint attribute,EGLint * value) const219 EGLBoolean egl_surface_t::getColorSpaceAttribute(EGLint attribute, EGLint* value) const {
220     if (attribute == EGL_GL_COLORSPACE_KHR) {
221         *value = colorSpace;
222         return EGL_TRUE;
223     }
224     return EGL_FALSE;
225 }
226 
getSmpte2086Attribute(EGLint attribute,EGLint * value) const227 EGLBoolean egl_surface_t::getSmpte2086Attribute(EGLint attribute, EGLint* value) const {
228     switch (attribute) {
229         case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
230             *value = egl_smpte2086_metadata.displayPrimaryRed.x;
231             return EGL_TRUE;
232             break;
233         case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
234             *value = egl_smpte2086_metadata.displayPrimaryRed.y;
235             return EGL_TRUE;
236             break;
237         case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
238             *value = egl_smpte2086_metadata.displayPrimaryGreen.x;
239             return EGL_TRUE;
240             break;
241         case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
242             *value = egl_smpte2086_metadata.displayPrimaryGreen.y;
243             return EGL_TRUE;
244             break;
245         case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
246             *value = egl_smpte2086_metadata.displayPrimaryBlue.x;
247             return EGL_TRUE;
248             break;
249         case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
250             *value = egl_smpte2086_metadata.displayPrimaryBlue.y;
251             return EGL_TRUE;
252             break;
253         case EGL_SMPTE2086_WHITE_POINT_X_EXT:
254             *value = egl_smpte2086_metadata.whitePoint.x;
255             return EGL_TRUE;
256             break;
257         case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
258             *value = egl_smpte2086_metadata.whitePoint.y;
259             return EGL_TRUE;
260             break;
261         case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
262             *value = egl_smpte2086_metadata.maxLuminance;
263             return EGL_TRUE;
264             break;
265         case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
266             *value = egl_smpte2086_metadata.minLuminance;
267             return EGL_TRUE;
268             break;
269     }
270     return EGL_FALSE;
271 }
272 
getCta8613Attribute(EGLint attribute,EGLint * value) const273 EGLBoolean egl_surface_t::getCta8613Attribute(EGLint attribute, EGLint* value) const {
274     switch (attribute) {
275         case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
276             *value = egl_cta861_3_metadata.maxContentLightLevel;
277             return EGL_TRUE;
278             break;
279         case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
280             *value = egl_cta861_3_metadata.maxFrameAverageLightLevel;
281             return EGL_TRUE;
282             break;
283     }
284     return EGL_FALSE;
285 }
286 
terminate()287 void egl_surface_t::terminate() {
288     disconnect();
289     egl_object_t::terminate();
290 }
291 
egl_context_t(EGLDisplay dpy,EGLContext context,EGLConfig config,egl_connection_t const * cnx,int version)292 egl_context_t::egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
293                              egl_connection_t const* cnx, int version)
294       : egl_object_t(get_display(dpy)),
295         dpy(dpy),
296         context(context),
297         config(config),
298         read(nullptr),
299         draw(nullptr),
300         cnx(cnx),
301         version(version) {}
302 
onLooseCurrent()303 void egl_context_t::onLooseCurrent() {
304     read = nullptr;
305     draw = nullptr;
306 }
307 
onMakeCurrent(EGLSurface draw,EGLSurface read)308 void egl_context_t::onMakeCurrent(EGLSurface draw, EGLSurface read) {
309     this->read = read;
310     this->draw = draw;
311 
312     /*
313      * Here we cache the GL_EXTENSIONS string for this context and we
314      * add the extensions always handled by the wrapper
315      */
316     if (!gl_extensions.empty()) return;
317 
318     // call the implementation's glGetString(GL_EXTENSIONS)
319     const char* exts = (const char*)gEGLImpl.hooks[version]->gl.glGetString(GL_EXTENSIONS);
320     if (!exts) return;
321 
322     // If this context is sharing with another context, and the other context was reset
323     // e.g. due to robustness failure, this context might also be reset and glGetString can
324     // return NULL.
325     gl_extensions = exts;
326     if (gl_extensions.find("GL_EXT_debug_marker") == std::string::npos) {
327         gl_extensions.insert(0, "GL_EXT_debug_marker ");
328         // eglGetProcAddress could return function pointers to these
329         // functions while they actually don't work. Fix them now.
330         __eglMustCastToProperFunctionPointerType* f;
331         f = (__eglMustCastToProperFunctionPointerType*)&gEGLImpl.hooks[version]
332                     ->gl.glInsertEventMarkerEXT;
333         if (*f != gl_noop) *f = gl_noop;
334         f = (__eglMustCastToProperFunctionPointerType*)&gEGLImpl.hooks[version]
335                     ->gl.glPushGroupMarkerEXT;
336         if (*f != gl_noop) *f = gl_noop;
337         f = (__eglMustCastToProperFunctionPointerType*)&gEGLImpl.hooks[version]
338                     ->gl.glPopGroupMarkerEXT;
339         if (*f != gl_noop) *f = gl_noop;
340     }
341 
342     // tokenize the supported extensions for the glGetStringi() wrapper
343     std::stringstream ss;
344     std::string str;
345     ss << gl_extensions;
346     while (ss >> str) {
347         tokenized_gl_extensions.push_back(str);
348     }
349 }
350 
351 }; // namespace android
352