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