1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "egl_wrapper_display.h"
17
18 #include "egl_defs.h"
19 #if USE_IGRAPHICS_EXTENDS_HOOKS
20 #include "egl_wrapper_hook.h"
21 #endif
22 #include "egl_wrapper_context.h"
23 #include "egl_wrapper_surface.h"
24 #include "thread_private_data_ctl.h"
25 #include "wrapper_log.h"
26 #include "egl_blob_cache.h"
27 #include "external_window.h"
28 #include "surface.h"
29 #include "window.h"
30
31 namespace OHOS {
32 static constexpr const char *VENDOR_VALUE = "OpenHarmony";
33 static constexpr const char *VERSION_VALUE_1_4 = "1.4 OpenHarmony EGL";
34 static constexpr const char *VERSION_VALUE_1_5 = "1.5 OpenHarmony EGL";
35 static constexpr const char *CLIENT_API_VALUE = "OpenGL_ES";
36 static constexpr const char *EXTENSION_VALUE =
37 "EGL_KHR_mutable_render_buffer "
38 "EGL_KHR_config_attribs "
39 "EGL_KHR_image_base "
40 "EGL_KHR_gl_colorspace "
41 "EGL_KHR_get_all_proc_addresses "
42 "EGL_KHR_no_config_context "
43 "EGL_IMG_context_priority "
44 "EGL_EXT_pixel_format_float "
45 "EGL_ARM_pixmap_multisample_discard "
46 "EGL_EXT_protected_content "
47 "EGL_ARM_implicit_external_sync "
48 "EGL_KHR_gl_texture_2D_image "
49 "EGL_KHR_gl_renderbuffer_image "
50 "EGL_KHR_create_context "
51 "EGL_KHR_surfaceless_context "
52 "EGL_KHR_gl_texture_cubemap_image "
53 "EGL_EXT_create_context_robustness "
54 "EGL_EXT_image_gl_colorspace "
55 "EGL_EXT_platform_base "
56 "EGL_ANDROID_presentation_time "
57 "EGL_ANDROID_get_native_client_buffer "
58 "EGL_ANDROID_native_fence_sync "
59 "EGL_KHR_partial_update "
60 "EGL_KHR_image "
61 "EGL_KHR_fence_sync "
62 "EGL_KHR_wait_sync "
63 "EGL_EXT_protected_surface "
64 ;
65
66 EglWrapperDisplay EglWrapperDisplay::wrapperDisp_;
67
EglWrapperDisplay()68 EglWrapperDisplay::EglWrapperDisplay() noexcept : disp_(EGL_NO_DISPLAY), refCnt_(0)
69 {
70 WLOGD("");
71 }
72
~EglWrapperDisplay()73 EglWrapperDisplay::~EglWrapperDisplay()
74 {
75 WLOGD("");
76 }
77
UpdateQueryValue(EGLint * major,EGLint * minor)78 void EglWrapperDisplay::UpdateQueryValue(EGLint *major, EGLint *minor)
79 {
80 if (minor != nullptr && major != nullptr) {
81 // 1 is major version, 5 is minor version.
82 versionValue_ = (*major == 1 && *minor == 5) ? VERSION_VALUE_1_5 : VERSION_VALUE_1_4;
83 }
84 vendorValue_ = VENDOR_VALUE;
85 clientApiValue_ = CLIENT_API_VALUE;
86 extensionValue_ = EXTENSION_VALUE;
87 }
88
Init(EGLint * major,EGLint * minor)89 EGLBoolean EglWrapperDisplay::Init(EGLint *major, EGLint *minor)
90 {
91 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
92 if (refCnt_ > 0) { // wait other thread init.
93 EglWrapperDispatchTablePtr table = &gWrapperHook;
94 if (major != nullptr) {
95 *major = table->major;
96 }
97 if (minor != nullptr) {
98 *minor = table->minor;
99 }
100 refCnt_++;
101 UpdateQueryValue(&table->major, &table->minor);
102 return EGL_TRUE;
103 }
104
105 ThreadPrivateDataCtl::SetGlHookTable(&gGlHookNoContext);
106 EglWrapperDispatchTablePtr table = &gWrapperHook;
107 table->major = -1;
108 table->minor = -1;
109 if (table->isLoad && table->egl.eglInitialize) {
110 if (table->egl.eglInitialize(disp_, &table->major, &table->minor)) {
111 WLOGD("initialized ver=%{public}d.%{public}d", table->major, table->minor);
112 if (major != nullptr) {
113 *major = table->major;
114 }
115 if (minor != nullptr) {
116 *minor = table->minor;
117 }
118 refCnt_++;
119 BlobCache::Get()->Init(this);
120 UpdateQueryValue(&table->major, &table->minor);
121 return EGL_TRUE;
122 } else {
123 WLOGE("eglInitialize Error.");
124 }
125 } else {
126 WLOGE("eglInitialize is invalid.");
127 }
128 return EGL_FALSE;
129 }
130
Terminate()131 EGLBoolean EglWrapperDisplay::Terminate()
132 {
133 WLOGD("");
134 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
135 if (refCnt_ == 0) {
136 WLOGI("display is not Init.");
137 return EGL_TRUE;
138 }
139
140 refCnt_--;
141 if (refCnt_ > 0) {
142 return EGL_TRUE;
143 }
144
145 EglWrapperDispatchTablePtr table = &gWrapperHook;
146 if (table->isLoad) {
147 if (table->egl.eglTerminate) {
148 BlobCache::Get()->Terminate();
149 ClearObjects();
150 return table->egl.eglTerminate(disp_);
151 }
152 }
153
154 WLOGE("eglTerminate is invalid.");
155 return EGL_FALSE;
156 }
157
InternalMakeCurrent(EglWrapperSurface * draw,EglWrapperSurface * read,EglWrapperContext * ctx,bool isAfterHook,EglWrapperContext * curCtx)158 EGLBoolean EglWrapperDisplay::InternalMakeCurrent(
159 EglWrapperSurface *draw, EglWrapperSurface *read, EglWrapperContext *ctx,
160 bool isAfterHook, EglWrapperContext *curCtx)
161 {
162 WLOGD("");
163 EGLContext actualCtx = EGL_NO_CONTEXT;
164 EGLSurface actualDraw = EGL_NO_SURFACE;
165 EGLSurface actualRead = EGL_NO_SURFACE;
166 if (draw != nullptr) {
167 actualDraw = draw->GetEglSurface();
168 }
169
170 if (read != nullptr) {
171 actualRead = read->GetEglSurface();
172 }
173
174 if (ctx != nullptr) {
175 actualCtx = ctx->GetEglContext();
176 }
177
178 EGLBoolean ret = EGL_FALSE;
179 EglWrapperDispatchTablePtr table = &gWrapperHook;
180 if (table->isLoad && table->egl.eglMakeCurrent) {
181 ret = table->egl.eglMakeCurrent(disp_, actualDraw, actualRead, actualCtx);
182 if (ret == EGL_TRUE) {
183 GlHookTable *hookTable = &gGlHookNoContext;
184 if (ctx != nullptr) {
185 hookTable = &gWrapperHook.gl;
186 ctx->SetCurrentSurface(draw, read);
187 }
188 #if USE_IGRAPHICS_EXTENDS_HOOKS
189 ChooseHookTable(isAfterHook, ctx, curCtx, &hookTable);
190 #endif
191 ThreadPrivateDataCtl::SetGlHookTable(hookTable);
192 ThreadPrivateDataCtl::SetContext(ctx);
193 } else {
194 WLOGE("eglMakeCurrent error.");
195 }
196 } else {
197 WLOGE("eglMakeCurrent is invalid.");
198 }
199 return ret;
200 }
201
202 #if USE_IGRAPHICS_EXTENDS_HOOKS
ChooseHookTable(bool isAfterHook,const EglWrapperContext * ctx,const EglWrapperContext * curCtx,GlHookTable ** ppHookTable)203 void EglWrapperDisplay::ChooseHookTable(bool isAfterHook,
204 const EglWrapperContext *ctx, const EglWrapperContext *curCtx,
205 GlHookTable **ppHookTable)
206 {
207 if (ppHookTable == nullptr) {
208 return;
209 }
210
211 if (isAfterHook) {
212 if (ctx == nullptr && curCtx != nullptr) {
213 *ppHookTable = &g_glHookCSDR;
214 }
215 } else {
216 EglWrapperHook& hookLayer(EglWrapperHook::GetInstance());
217 if (hookLayer.IsInit() && hookLayer.gtx.gtxGetSingleThreadStatus()) {
218 *ppHookTable = &g_glHookSingle;
219 }
220 }
221 }
222 #endif
223
MakeCurrent(EGLSurface draw,EGLSurface read,EGLContext ctx)224 EGLBoolean EglWrapperDisplay::MakeCurrent(EGLSurface draw, EGLSurface read, EGLContext ctx)
225 {
226 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
227
228 EglWrapperContext *ctxPtr = nullptr;
229 EglWrapperSurface *surDrawPtr = nullptr;
230 EglWrapperSurface *surReadPtr = nullptr;
231
232 if (ctx != EGL_NO_CONTEXT) {
233 ctxPtr = EglWrapperContext::GetWrapperContext(ctx);
234 if (!CheckObject(ctxPtr)) {
235 WLOGE("EGLContext is invalid.");
236 ThreadPrivateDataCtl::SetError(EGL_BAD_CONTEXT);
237 return EGL_FALSE;
238 }
239 } else {
240 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
241 WLOGE("EGLContext and EGLSurface is bad match.");
242 ThreadPrivateDataCtl::SetError(EGL_BAD_MATCH);
243 return EGL_FALSE;
244 }
245 if (ThreadPrivateDataCtl::GetContext() == EGL_NO_CONTEXT) {
246 WLOGI("There is just no current context. skip");
247 return EGL_TRUE;
248 }
249 }
250
251 if (draw != EGL_NO_SURFACE) {
252 surDrawPtr = EglWrapperSurface::GetWrapperSurface(draw);
253 if (!CheckObject(surDrawPtr)) {
254 WLOGE("EGLSurface is invalid.");
255 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
256 return EGL_FALSE;
257 }
258 }
259
260 if (read != EGL_NO_SURFACE) {
261 surReadPtr = EglWrapperSurface::GetWrapperSurface(read);
262 if (!CheckObject(surReadPtr)) {
263 WLOGE("EGLSurface is invalid.");
264 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
265 return EGL_FALSE;
266 }
267 }
268
269 return InternalMakeCurrent(surDrawPtr, surReadPtr, ctxPtr);
270 }
271
272 #if USE_IGRAPHICS_EXTENDS_HOOKS
MakeCurrentAfterHook(EGLSurface draw,EGLSurface read,EGLContext ctx)273 EGLBoolean EglWrapperDisplay::MakeCurrentAfterHook(EGLSurface draw, EGLSurface read, EGLContext ctx)
274 {
275 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
276
277 EglWrapperContext *ctxPtr = nullptr;
278 EglWrapperSurface *surDrawPtr = nullptr;
279 EglWrapperSurface *surReadPtr = nullptr;
280
281 EGLContext curC = ThreadPrivateDataCtl::GetContext();
282 EglWrapperContext *curCtx = EglWrapperContext::GetWrapperContext(curC);
283
284 if (ctx != EGL_NO_CONTEXT) {
285 ctxPtr = EglWrapperContext::GetWrapperContext(ctx);
286 if (!CheckObject(ctxPtr)) {
287 WLOGE("EGLContext is invalid.");
288 ThreadPrivateDataCtl::SetError(EGL_BAD_CONTEXT);
289 return EGL_FALSE;
290 }
291 } else {
292 if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE) {
293 WLOGE("EGLContext and EGLSurface is bad match.");
294 ThreadPrivateDataCtl::SetError(EGL_BAD_MATCH);
295 return EGL_FALSE;
296 }
297 if (ThreadPrivateDataCtl::GetContext() == EGL_NO_CONTEXT) {
298 WLOGI("There is just no current context. skip");
299 return EGL_TRUE;
300 }
301 }
302
303 if (draw != EGL_NO_SURFACE) {
304 surDrawPtr = EglWrapperSurface::GetWrapperSurface(draw);
305 if (!CheckObject(surDrawPtr)) {
306 WLOGE("EGLSurface is invalid.");
307 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
308 return EGL_FALSE;
309 }
310 }
311
312 if (read != EGL_NO_SURFACE) {
313 surReadPtr = EglWrapperSurface::GetWrapperSurface(read);
314 if (!CheckObject(surReadPtr)) {
315 WLOGE("EGLSurface is invalid.");
316 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
317 return EGL_FALSE;
318 }
319 }
320 return InternalMakeCurrent(surDrawPtr, surReadPtr, ctxPtr, true, curCtx);
321 }
322 #endif
323
GetWrapperDisplay(EGLDisplay display)324 EglWrapperDisplay *EglWrapperDisplay::GetWrapperDisplay(EGLDisplay display)
325 {
326 WLOGD("");
327 EglWrapperDisplay *disp = reinterpret_cast<EglWrapperDisplay *>(display);
328 if (disp == &wrapperDisp_) {
329 return disp;
330 }
331 WLOGE("invalid display pointer.");
332 return nullptr;
333 }
334
GetEglNativeDisplay(EGLenum platform,EGLNativeDisplayType disp,const EGLAttrib * attribList)335 EGLDisplay EglWrapperDisplay::GetEglNativeDisplay(EGLenum platform,
336 EGLNativeDisplayType disp, const EGLAttrib *attribList)
337 {
338 WLOGD("");
339 EglWrapperDispatchTablePtr table = &gWrapperHook;
340 if (table->isLoad) {
341 if (table->egl.eglGetPlatformDisplay) {
342 disp_ = table->egl.eglGetPlatformDisplay(platform, disp, attribList);
343 }
344
345 if (disp_ == EGL_NO_DISPLAY) {
346 if (attribList) {
347 WLOGW("attribList ignored.");
348 }
349
350 if (table->egl.eglGetDisplay) {
351 disp_ = table->egl.eglGetDisplay(disp);
352 } else {
353 WLOGE("eglGetDisplay is invalid.");
354 }
355 }
356 } else {
357 WLOGE("EglWrapperDispatchTable is not load.");
358 }
359
360 WLOGD("");
361
362 return (disp_ == EGL_NO_DISPLAY) ? disp_ : (EGLDisplay)&wrapperDisp_;
363 }
364
GetEglNativeDisplayExt(EGLenum platform,void * disp,const EGLint * attribList)365 EGLDisplay EglWrapperDisplay::GetEglNativeDisplayExt(EGLenum platform,
366 void *disp, const EGLint *attribList)
367 {
368 WLOGD("");
369 EglWrapperDispatchTablePtr table = &gWrapperHook;
370 if (table->isLoad && table->egl.eglGetPlatformDisplayEXT) {
371 disp_ = table->egl.eglGetPlatformDisplayEXT(platform, disp, attribList);
372 } else {
373 WLOGE("eglGetPlatformDisplayEXT is invalid.");
374 }
375
376 return (disp_ == EGL_NO_DISPLAY) ? disp_ : (EGLDisplay)&wrapperDisp_;
377 }
378
GetEglDisplay(EGLenum platform,EGLNativeDisplayType disp,const EGLAttrib * attribList)379 EGLDisplay EglWrapperDisplay::GetEglDisplay(EGLenum platform,
380 EGLNativeDisplayType disp, const EGLAttrib *attribList)
381 {
382 WLOGD("");
383 return wrapperDisp_.GetEglNativeDisplay(platform, disp, attribList);
384 }
385
GetEglDisplayExt(EGLenum platform,void * disp,const EGLint * attribList)386 EGLDisplay EglWrapperDisplay::GetEglDisplayExt(EGLenum platform,
387 void *disp, const EGLint *attribList)
388 {
389 return wrapperDisp_.GetEglNativeDisplayExt(platform, disp, attribList);
390 }
391
ValidateEglContext(EGLContext ctx)392 bool EglWrapperDisplay::ValidateEglContext(EGLContext ctx)
393 {
394 WLOGD("");
395 return false;
396 }
397
ValidateEglSurface(EGLSurface surf)398 bool EglWrapperDisplay::ValidateEglSurface(EGLSurface surf)
399 {
400 WLOGD("");
401 return false;
402 }
403
404 #if USE_IGRAPHICS_EXTENDS_HOOKS
ChooseGlesVersion(const EGLint * attribList)405 int EglWrapperDisplay::ChooseGlesVersion(const EGLint *attribList)
406 {
407 int version = EglWrapperDispatchTable::GLESV1_INDEX;
408 if (attribList) {
409 while (*attribList != EGL_NONE) {
410 GLint attr = *attribList++;
411 GLint value = *attribList++;
412 if (attr == EGL_CONTEXT_CLIENT_VERSION && (value == 2 || value == 3)) { // 2:version 3:version
413 version = EglWrapperDispatchTable::GLESV2_INDEX;
414 }
415 }
416 }
417 return version;
418 }
419 #endif
420
CreateEglContext(EGLConfig config,EGLContext shareList,const EGLint * attribList)421 EGLContext EglWrapperDisplay::CreateEglContext(EGLConfig config, EGLContext shareList, const EGLint *attribList)
422 {
423 WLOGD("");
424 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
425
426 EGLContext shareCtx = EGL_NO_CONTEXT;
427 if (shareList != EGL_NO_CONTEXT) {
428 EglWrapperContext *ctxPtr = EglWrapperContext::GetWrapperContext(shareList);
429 if (!CheckObject(ctxPtr)) {
430 WLOGE("EGLContext is invalid.");
431 ThreadPrivateDataCtl::SetError(EGL_BAD_CONTEXT);
432 return EGL_NO_CONTEXT;
433 }
434 shareCtx = ctxPtr->GetEglContext();
435 }
436
437 EglWrapperDispatchTablePtr table = &gWrapperHook;
438 if (table->isLoad && table->egl.eglCreateContext) {
439 EGLContext context = table->egl.eglCreateContext(disp_, config, shareCtx, attribList);
440 if (context != EGL_NO_CONTEXT) {
441 #if USE_IGRAPHICS_EXTENDS_HOOKS
442 return new EglWrapperContext(this, context, ChooseGlesVersion(attribList));
443 #else
444 return new EglWrapperContext(this, context);
445 #endif
446 } else {
447 WLOGE("egl.eglCreateContext error.");
448 }
449 } else {
450 WLOGE("eglCreateContext is invalid.");
451 }
452
453 return EGL_NO_CONTEXT;
454 }
455
DestroyEglContext(EGLContext context)456 EGLBoolean EglWrapperDisplay::DestroyEglContext(EGLContext context)
457 {
458 WLOGD("");
459 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
460
461 EglWrapperContext *ctxPtr = EglWrapperContext::GetWrapperContext(context);
462 if (!CheckObject(ctxPtr)) {
463 WLOGE("EGLContext is invalid.");
464 ThreadPrivateDataCtl::SetError(EGL_BAD_CONTEXT);
465 return EGL_FALSE;
466 }
467 EGLContext ctx = ctxPtr->GetEglContext();
468
469 EGLBoolean ret = EGL_FALSE;
470 EglWrapperDispatchTablePtr table = &gWrapperHook;
471 if (table->isLoad && table->egl.eglDestroyContext) {
472 ret = table->egl.eglDestroyContext(disp_, ctx);
473 if (ret == EGL_TRUE) {
474 ctxPtr->Destroy();
475 } else {
476 WLOGE("eglDestroyContext error.");
477 }
478 } else {
479 WLOGE("eglDestroyContext is invalid.");
480 }
481
482 return ret;
483 }
484
485 // Get the colorspace value that should be reported from queries.
486 // When the colorspace is unknown (no attribute passed), default to reporting LINEAR.
GetReportedColorSpace(EGLint colorSpace)487 static EGLint GetReportedColorSpace(EGLint colorSpace)
488 {
489 return colorSpace == EGL_UNKNOWN ? EGL_GL_COLORSPACE_LINEAR_KHR : colorSpace;
490 }
491
CreateEglSurface(EGLConfig config,NativeWindowType window,const EGLint * attribList)492 EGLSurface EglWrapperDisplay::CreateEglSurface(EGLConfig config, NativeWindowType window, const EGLint *attribList)
493 {
494 WLOGD("");
495 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
496
497 if (!window) {
498 WLOGE("NativeWindowType window is invalid.");
499 ThreadPrivateDataCtl::SetError(EGL_BAD_NATIVE_WINDOW);
500 return EGL_NO_SURFACE;
501 }
502
503 // select correct colorspace and dataspace based on user's attribute list.
504 EGLint colorSpace = EGL_UNKNOWN;
505 for (const EGLint* attr = attribList; attr && attr[0] != EGL_NONE; attr += 2) {
506 if (attr[0] == EGL_GL_COLORSPACE_KHR &&
507 (attr[1] == EGL_GL_COLORSPACE_LINEAR_KHR || attr[1] == EGL_GL_COLORSPACE_SRGB_KHR)) {
508 colorSpace = static_cast<EGLint>(attr[1]);
509 }
510 }
511
512 EglWrapperDispatchTablePtr table = &gWrapperHook;
513 if (table->isLoad && table->egl.eglCreateWindowSurface) {
514 EGLSurface surf = table->egl.eglCreateWindowSurface(disp_, config, window, attribList);
515 if (surf != EGL_NO_SURFACE) {
516 return new EglWrapperSurface(this, surf, window, GetReportedColorSpace(colorSpace));
517 } else {
518 WLOGE("egl.eglCreateWindowSurface error.");
519 }
520 } else {
521 WLOGE("eglCreateWindowSurface is invalid.");
522 }
523
524 return EGL_NO_SURFACE;
525 }
526
DestroyEglSurface(EGLSurface surf)527 EGLBoolean EglWrapperDisplay::DestroyEglSurface(EGLSurface surf)
528 {
529 WLOGD("");
530 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
531
532 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
533 if (!CheckObject(surfPtr)) {
534 WLOGE("EGLSurface is invalid.");
535 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
536 return EGL_FALSE;
537 }
538 EGLSurface sur = surfPtr->GetEglSurface();
539
540 EGLBoolean ret = EGL_FALSE;
541 EglWrapperDispatchTablePtr table = &gWrapperHook;
542 if (table->isLoad && table->egl.eglDestroySurface) {
543 ret = table->egl.eglDestroySurface(disp_, sur);
544 if (ret == EGL_TRUE) {
545 surfPtr->Destroy();
546 } else {
547 WLOGE("eglDestroySurface error.");
548 }
549 } else {
550 WLOGE("eglDestroySurface is invalid.");
551 }
552
553 return ret;
554 }
555
AddObject(EglWrapperObject * obj)556 void EglWrapperDisplay::AddObject(EglWrapperObject *obj)
557 {
558 std::lock_guard<std::mutex> lock(lockMutex_);
559 objects_.insert(obj);
560 }
561
RemoveObject(EglWrapperObject * obj)562 void EglWrapperDisplay::RemoveObject(EglWrapperObject *obj)
563 {
564 std::lock_guard<std::mutex> lock(lockMutex_);
565 objects_.erase(obj);
566 }
567
ClearObjects()568 void EglWrapperDisplay::ClearObjects()
569 {
570 std::lock_guard<std::mutex> lock(lockMutex_);
571 for (auto obj : objects_) {
572 obj->Release();
573 }
574 objects_.clear();
575 }
576
CheckObject(EglWrapperObject * obj)577 bool EglWrapperDisplay::CheckObject(EglWrapperObject *obj)
578 {
579 std::lock_guard<std::mutex> lock(lockMutex_);
580 if (objects_.find(obj) != objects_.end()) {
581 if (obj->GetDisplay() == this) {
582 return true;
583 }
584 }
585 return false;
586 }
587
CopyBuffers(EGLSurface surf,NativePixmapType target)588 EGLBoolean EglWrapperDisplay::CopyBuffers(EGLSurface surf, NativePixmapType target)
589 {
590 WLOGD("");
591 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
592
593 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
594 if (!CheckObject(surfPtr)) {
595 WLOGE("EGLSurface is invalid.");
596 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
597 return EGL_FALSE;
598 }
599
600 EGLBoolean ret = EGL_FALSE;
601 EglWrapperDispatchTablePtr table = &gWrapperHook;
602 if (table->isLoad && table->egl.eglCopyBuffers) {
603 ret = table->egl.eglCopyBuffers(disp_, surfPtr->GetEglSurface(), target);
604 } else {
605 WLOGE("eglCopyBuffers is invalid.");
606 }
607
608 return ret;
609 }
610
CreatePbufferSurface(EGLConfig config,const EGLint * attribList)611 EGLSurface EglWrapperDisplay::CreatePbufferSurface(EGLConfig config, const EGLint *attribList)
612 {
613 WLOGD("");
614 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
615
616 EglWrapperDispatchTablePtr table = &gWrapperHook;
617 if (table->isLoad && table->egl.eglCreatePbufferSurface) {
618 EGLSurface surf = table->egl.eglCreatePbufferSurface(disp_, config, attribList);
619 if (surf != EGL_NO_SURFACE) {
620 return new EglWrapperSurface(this, surf);
621 } else {
622 WLOGE("egl.eglCreatePbufferSurface error.");
623 }
624 } else {
625 WLOGE("eglCreatePbufferSurface is invalid.");
626 }
627
628 return EGL_NO_SURFACE;
629 }
630
CreatePixmapSurface(EGLConfig config,EGLNativePixmapType pixmap,const EGLint * attribList)631 EGLSurface EglWrapperDisplay::CreatePixmapSurface(EGLConfig config,
632 EGLNativePixmapType pixmap, const EGLint* attribList)
633 {
634 WLOGD("");
635 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
636
637 EglWrapperDispatchTablePtr table = &gWrapperHook;
638 if (table->isLoad && table->egl.eglCreatePixmapSurface) {
639 EGLSurface surf = table->egl.eglCreatePixmapSurface(disp_, config, pixmap, attribList);
640 if (surf != EGL_NO_SURFACE) {
641 return new EglWrapperSurface(this, surf);
642 } else {
643 WLOGE("egl.eglCreatePixmapSurface error.");
644 }
645 } else {
646 WLOGE("eglCreatePixmapSurface is invalid.");
647 }
648
649 return EGL_NO_SURFACE;
650 }
651
QueryContext(EGLContext ctx,EGLint attribute,EGLint * value)652 EGLBoolean EglWrapperDisplay::QueryContext(EGLContext ctx, EGLint attribute, EGLint *value)
653 {
654 WLOGD("");
655 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
656
657 EglWrapperContext *ctxPtr = EglWrapperContext::GetWrapperContext(ctx);
658 if (!CheckObject(ctxPtr)) {
659 WLOGE("EGLContext is invalid.");
660 ThreadPrivateDataCtl::SetError(EGL_BAD_CONTEXT);
661 return EGL_FALSE;
662 }
663
664 EGLBoolean ret = EGL_FALSE;
665 EglWrapperDispatchTablePtr table = &gWrapperHook;
666 if (table->isLoad && table->egl.eglQueryContext) {
667 ret = table->egl.eglQueryContext(disp_,
668 ctxPtr->GetEglContext(), attribute, value);
669 } else {
670 WLOGE("eglQueryContext is invalid.");
671 }
672
673 return ret;
674 }
675
QuerySurface(EGLSurface surf,EGLint attribute,EGLint * value)676 EGLBoolean EglWrapperDisplay::QuerySurface(EGLSurface surf, EGLint attribute, EGLint *value)
677 {
678 WLOGD("");
679 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
680
681 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
682 if (!CheckObject(surfPtr)) {
683 WLOGE("EGLSurface is invalid.");
684 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
685 return EGL_FALSE;
686 }
687
688 if (surfPtr->GetColorSpaceAttribute(attribute, value)) {
689 return EGL_TRUE;
690 }
691
692 EGLBoolean ret = EGL_FALSE;
693 EglWrapperDispatchTablePtr table = &gWrapperHook;
694 if (table->isLoad && table->egl.eglQuerySurface) {
695 ret = table->egl.eglQuerySurface(disp_,
696 surfPtr->GetEglSurface(), attribute, value);
697 } else {
698 WLOGE("eglQuerySurface is invalid.");
699 }
700
701 return ret;
702 }
703
SwapBuffers(EGLSurface surf)704 EGLBoolean EglWrapperDisplay::SwapBuffers(EGLSurface surf)
705 {
706 WLOGD("");
707 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
708
709 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
710 if (!CheckObject(surfPtr)) {
711 if (surfPtr->GetEglSurface() == nullptr) {
712 WLOGE("INparament is invalid.");
713 return EGL_FALSE;
714 }
715 WLOGE("EGLSurface is invalid.");
716 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
717 return EGL_FALSE;
718 }
719
720 EGLBoolean ret = EGL_FALSE;
721 EglWrapperDispatchTablePtr table = &gWrapperHook;
722 if (table->isLoad && table->egl.eglSwapBuffers) {
723 ret = table->egl.eglSwapBuffers(disp_, surfPtr->GetEglSurface());
724 } else {
725 WLOGE("eglSwapBuffers is invalid.");
726 }
727
728 return ret;
729 }
730
BindTexImage(EGLSurface surf,EGLint buffer)731 EGLBoolean EglWrapperDisplay::BindTexImage(EGLSurface surf, EGLint buffer)
732 {
733 WLOGD("");
734 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
735
736 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
737 if (!CheckObject(surfPtr)) {
738 WLOGE("EGLSurface is invalid.");
739 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
740 return EGL_FALSE;
741 }
742
743 EGLBoolean ret = EGL_FALSE;
744 EglWrapperDispatchTablePtr table = &gWrapperHook;
745 if (table->isLoad && table->egl.eglBindTexImage) {
746 ret = table->egl.eglBindTexImage(disp_, surfPtr->GetEglSurface(), buffer);
747 } else {
748 WLOGE("eglBindTexImage is invalid.");
749 }
750
751 return ret;
752 }
753
ReleaseTexImage(EGLSurface surf,EGLint buffer)754 EGLBoolean EglWrapperDisplay::ReleaseTexImage(EGLSurface surf, EGLint buffer)
755 {
756 WLOGD("");
757 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
758
759 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
760 if (!CheckObject(surfPtr)) {
761 WLOGE("EGLSurface is invalid.");
762 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
763 return EGL_FALSE;
764 }
765
766 EGLBoolean ret = EGL_FALSE;
767 EglWrapperDispatchTablePtr table = &gWrapperHook;
768 if (table->isLoad && table->egl.eglReleaseTexImage) {
769 ret = table->egl.eglReleaseTexImage(disp_, surfPtr->GetEglSurface(), buffer);
770 } else {
771 WLOGE("eglReleaseTexImage is invalid.");
772 }
773
774 return ret;
775 }
776
SurfaceAttrib(EGLSurface surf,EGLint attribute,EGLint value)777 EGLBoolean EglWrapperDisplay::SurfaceAttrib(EGLSurface surf, EGLint attribute, EGLint value)
778 {
779 WLOGD("");
780 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
781
782 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
783 if (!CheckObject(surfPtr)) {
784 WLOGE("EGLSurface is invalid.");
785 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
786 return EGL_FALSE;
787 }
788
789 EGLBoolean ret = EGL_FALSE;
790 EglWrapperDispatchTablePtr table = &gWrapperHook;
791 if (table->isLoad && table->egl.eglSurfaceAttrib) {
792 ret = table->egl.eglSurfaceAttrib(disp_,
793 surfPtr->GetEglSurface(), attribute, value);
794 } else {
795 WLOGE("eglSurfaceAttrib is invalid.");
796 }
797
798 return ret;
799 }
800
CreatePbufferFromClientBuffer(EGLenum buftype,EGLClientBuffer buffer,EGLConfig config,const EGLint * attribList)801 EGLSurface EglWrapperDisplay::CreatePbufferFromClientBuffer(
802 EGLenum buftype, EGLClientBuffer buffer,
803 EGLConfig config, const EGLint *attribList)
804 {
805 WLOGD("");
806 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
807
808 EglWrapperDispatchTablePtr table = &gWrapperHook;
809 if (table->isLoad && table->egl.eglCreatePbufferFromClientBuffer) {
810 EGLSurface surf = table->egl.eglCreatePbufferFromClientBuffer(
811 disp_, buftype, buffer, config, attribList);
812 if (surf != EGL_NO_SURFACE) {
813 return new EglWrapperSurface(this, surf);
814 } else {
815 WLOGE("egl.eglCreatePbufferFromClientBuffer error.");
816 }
817 } else {
818 WLOGE("eglCreatePbufferFromClientBuffer is invalid.");
819 }
820
821 return EGL_NO_SURFACE;
822 }
823
CreateImage(EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLAttrib * attribList)824 EGLImage EglWrapperDisplay::CreateImage(EGLContext ctx, EGLenum target,
825 EGLClientBuffer buffer, const EGLAttrib *attribList)
826 {
827 WLOGD("");
828 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
829
830 EGLContext actualCtx = EGL_NO_CONTEXT;
831 if (ctx != EGL_NO_CONTEXT) {
832 EglWrapperContext *ctxPtr = EglWrapperContext::GetWrapperContext(ctx);
833 if (CheckObject(ctxPtr)) {
834 actualCtx = ctxPtr->GetEglContext();
835 }
836 }
837
838 EglWrapperDispatchTablePtr table = &gWrapperHook;
839 if (table->isLoad && table->egl.eglCreateImage) {
840 return table->egl.eglCreateImage(disp_, actualCtx, target, buffer, attribList);
841 } else {
842 WLOGE("eglCreateImage is invalid.");
843 }
844
845 return EGL_NO_IMAGE_KHR;
846 }
847
DestroyImage(EGLImage img)848 EGLBoolean EglWrapperDisplay::DestroyImage(EGLImage img)
849 {
850 WLOGD("");
851 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
852
853 EGLBoolean ret = EGL_FALSE;
854 EglWrapperDispatchTablePtr table = &gWrapperHook;
855 if (table->isLoad && table->egl.eglDestroyImage) {
856 ret = table->egl.eglDestroyImage(disp_, img);
857 } else {
858 WLOGE("eglDestroyImage is invalid.");
859 }
860
861 return ret;
862 }
863
CreatePlatformWindowSurface(EGLConfig config,void * nativeWindow,const EGLAttrib * attribList)864 EGLSurface EglWrapperDisplay::CreatePlatformWindowSurface(EGLConfig config,
865 void *nativeWindow, const EGLAttrib *attribList)
866 {
867 WLOGD("");
868 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
869
870 if (!nativeWindow) {
871 WLOGE("nativeWindow is invalid.");
872 ThreadPrivateDataCtl::SetError(EGL_BAD_NATIVE_WINDOW);
873 return EGL_NO_SURFACE;
874 }
875
876 EglWrapperDispatchTablePtr table = &gWrapperHook;
877 if (table->isLoad && table->egl.eglCreatePlatformWindowSurface) {
878 EGLSurface surf = table->egl.eglCreatePlatformWindowSurface(disp_,
879 config, nativeWindow, attribList);
880 if (surf != EGL_NO_SURFACE) {
881 return new EglWrapperSurface(this, surf);
882 } else {
883 WLOGE("egl.eglCreatePlatformWindowSurface error.");
884 }
885 } else {
886 WLOGE("eglCreatePlatformWindowSurface is invalid.");
887 }
888
889 return EGL_NO_SURFACE;
890 }
891
CreatePlatformPixmapSurface(EGLConfig config,void * nativePixmap,const EGLAttrib * attribList)892 EGLSurface EglWrapperDisplay::CreatePlatformPixmapSurface(EGLConfig config,
893 void *nativePixmap, const EGLAttrib *attribList)
894 {
895 WLOGD("");
896 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
897
898 if (!nativePixmap) {
899 WLOGE("nativePixmap is invalid.");
900 ThreadPrivateDataCtl::SetError(EGL_BAD_NATIVE_WINDOW);
901 return EGL_NO_SURFACE;
902 }
903
904 EglWrapperDispatchTablePtr table = &gWrapperHook;
905 if (table->isLoad && table->egl.eglCreatePlatformPixmapSurface) {
906 EGLSurface surf = table->egl.eglCreatePlatformPixmapSurface(disp_,
907 config, nativePixmap, attribList);
908 if (surf != EGL_NO_SURFACE) {
909 return new EglWrapperSurface(this, surf);
910 } else {
911 WLOGE("egl.eglCreatePlatformPixmapSurface error.");
912 }
913 } else {
914 WLOGE("eglCreatePlatformPixmapSurface is invalid.");
915 }
916
917 return EGL_NO_SURFACE;
918 }
919
LockSurfaceKHR(EGLSurface surf,const EGLint * attribList)920 EGLBoolean EglWrapperDisplay::LockSurfaceKHR(EGLSurface surf, const EGLint *attribList)
921 {
922 WLOGD("");
923 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
924
925 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
926 if (!CheckObject(surfPtr)) {
927 WLOGE("EGLSurface is invalid.");
928 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
929 return EGL_FALSE;
930 }
931
932 EGLBoolean ret = EGL_FALSE;
933 EglWrapperDispatchTablePtr table = &gWrapperHook;
934 if (table->isLoad && table->egl.eglLockSurfaceKHR) {
935 ret = table->egl.eglLockSurfaceKHR(disp_,
936 surfPtr->GetEglSurface(), attribList);
937 } else {
938 WLOGE("eglLockSurfaceKHR is invalid.");
939 }
940
941 return ret;
942 }
943
UnlockSurfaceKHR(EGLSurface surf)944 EGLBoolean EglWrapperDisplay::UnlockSurfaceKHR(EGLSurface surf)
945 {
946 WLOGD("");
947 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
948
949 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
950 if (!CheckObject(surfPtr)) {
951 WLOGE("EGLSurface is invalid.");
952 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
953 return EGL_FALSE;
954 }
955
956 EGLBoolean ret = EGL_FALSE;
957 EglWrapperDispatchTablePtr table = &gWrapperHook;
958 if (table->isLoad && table->egl.eglUnlockSurfaceKHR) {
959 ret = table->egl.eglUnlockSurfaceKHR(disp_, surfPtr->GetEglSurface());
960 } else {
961 WLOGE("eglUnlockSurfaceKHR is invalid.");
962 }
963
964 return ret;
965 }
966
CreateImageKHR(EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLint * attribList)967 EGLImageKHR EglWrapperDisplay::CreateImageKHR(EGLContext ctx, EGLenum target,
968 EGLClientBuffer buffer, const EGLint *attribList)
969 {
970 WLOGD("");
971 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
972
973 EGLContext actualCtx = EGL_NO_CONTEXT;
974 if (ctx != EGL_NO_CONTEXT) {
975 EglWrapperContext *ctxPtr = EglWrapperContext::GetWrapperContext(ctx);
976 if (CheckObject(ctxPtr)) {
977 actualCtx = ctxPtr->GetEglContext();
978 }
979 }
980
981 EglWrapperDispatchTablePtr table = &gWrapperHook;
982 if (table->isLoad && table->egl.eglCreateImageKHR) {
983 return table->egl.eglCreateImageKHR(disp_, actualCtx, target, buffer, attribList);
984 } else {
985 WLOGE("eglCreateImageKHR is invalid.");
986 }
987
988 return EGL_NO_IMAGE_KHR;
989 }
990
DestroyImageKHR(EGLImageKHR img)991 EGLBoolean EglWrapperDisplay::DestroyImageKHR(EGLImageKHR img)
992 {
993 WLOGD("");
994 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
995
996 EGLBoolean ret = EGL_FALSE;
997 EglWrapperDispatchTablePtr table = &gWrapperHook;
998 if (table->isLoad && table->egl.eglDestroyImageKHR) {
999 ret = table->egl.eglDestroyImageKHR(disp_, img);
1000 } else {
1001 WLOGE("eglDestroyImageKHR is invalid.");
1002 }
1003
1004 return ret;
1005 }
1006
CreateStreamProducerSurfaceKHR(EGLConfig config,EGLStreamKHR stream,const EGLint * attribList)1007 EGLSurface EglWrapperDisplay::CreateStreamProducerSurfaceKHR(EGLConfig config,
1008 EGLStreamKHR stream, const EGLint *attribList)
1009 {
1010 WLOGD("");
1011 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1012
1013 EglWrapperDispatchTablePtr table = &gWrapperHook;
1014 if (table->isLoad && table->egl.eglCreateStreamProducerSurfaceKHR) {
1015 EGLSurface surf = table->egl.eglCreateStreamProducerSurfaceKHR(
1016 disp_, config, stream, attribList);
1017 if (surf != EGL_NO_SURFACE) {
1018 return new EglWrapperSurface(this, surf);
1019 } else {
1020 WLOGE("egl.eglCreateStreamProducerSurfaceKHR error.");
1021 }
1022 } else {
1023 WLOGE("eglCreateStreamProducerSurfaceKHR is invalid.");
1024 }
1025
1026 return EGL_NO_SURFACE;
1027 }
1028
SwapBuffersWithDamageKHR(EGLSurface draw,EGLint * rects,EGLint nRects)1029 EGLBoolean EglWrapperDisplay::SwapBuffersWithDamageKHR(EGLSurface draw, EGLint *rects, EGLint nRects)
1030 {
1031 WLOGD("");
1032 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1033
1034 EglWrapperSurface *surfacePtr = EglWrapperSurface::GetWrapperSurface(draw);
1035 if (!CheckObject(surfacePtr)) {
1036 WLOGE("EGLSurface is invalid.");
1037 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1038 return EGL_FALSE;
1039 }
1040
1041 if (nRects < 0 || (nRects > 0 && rects == NULL)) {
1042 WLOGE("Paramter error.");
1043 ThreadPrivateDataCtl::SetError(EGL_BAD_PARAMETER);
1044 return EGL_FALSE;
1045 }
1046
1047 EGLBoolean ret = EGL_FALSE;
1048 EglWrapperDispatchTablePtr table = &gWrapperHook;
1049 if (table->isLoad && table->egl.eglSwapBuffersWithDamageKHR) {
1050 ret = table->egl.eglSwapBuffersWithDamageKHR(
1051 disp_, surfacePtr->GetEglSurface(), rects, nRects);
1052 } else {
1053 WLOGE("eglSwapBuffersWithDamageKHR is invalid.");
1054 }
1055
1056 return ret;
1057 }
1058
SetDamageRegionKHR(EGLSurface surf,EGLint * rects,EGLint nRects)1059 EGLBoolean EglWrapperDisplay::SetDamageRegionKHR(EGLSurface surf, EGLint *rects, EGLint nRects)
1060 {
1061 WLOGD("");
1062 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1063
1064 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
1065 if (!CheckObject(surfPtr)) {
1066 WLOGE("EGLSurface is invalid.");
1067 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1068 return EGL_FALSE;
1069 }
1070
1071 if (nRects < 0 || (nRects > 0 && rects == nullptr)) {
1072 WLOGE("Paramter error.");
1073 ThreadPrivateDataCtl::SetError(EGL_BAD_PARAMETER);
1074 return EGL_FALSE;
1075 }
1076
1077 EGLBoolean ret = EGL_FALSE;
1078 EglWrapperDispatchTablePtr table = &gWrapperHook;
1079 if (table->isLoad && table->egl.eglSetDamageRegionKHR) {
1080 ret = table->egl.eglSetDamageRegionKHR(
1081 disp_, surfPtr->GetEglSurface(), rects, nRects);
1082 } else {
1083 WLOGE("eglSetDamageRegionKHR is invalid.");
1084 }
1085
1086 return ret;
1087 }
1088
GetCompositorTimingSupportedANDROID(EGLSurface surface,EGLint name)1089 EGLBoolean EglWrapperDisplay::GetCompositorTimingSupportedANDROID(EGLSurface surface, EGLint name)
1090 {
1091 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1092
1093 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surface);
1094 if (!CheckObject(surfPtr)) {
1095 WLOGE("EGLSurface is invalid.");
1096 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1097 return EGL_FALSE;
1098 }
1099
1100 if (surfPtr->GetNativeWindow() == nullptr) {
1101 WLOGE("GetCompositorTimingSupportedANDROID native window is nullptr.");
1102 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1103 return EGL_FALSE;
1104 }
1105
1106 switch (name) {
1107 case EGL_COMPOSITE_DEADLINE_ANDROID:
1108 case EGL_COMPOSITE_INTERVAL_ANDROID:
1109 case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
1110 return EGL_TRUE;
1111 default:
1112 return EGL_FALSE;
1113 }
1114 }
1115
GetFrameTimestampSupportedANDROID(EGLSurface surface,EGLint timestamp)1116 EGLBoolean EglWrapperDisplay::GetFrameTimestampSupportedANDROID(EGLSurface surface, EGLint timestamp)
1117 {
1118 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1119
1120 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surface);
1121 if (!CheckObject(surfPtr)) {
1122 WLOGE("EGLSurface is invalid.");
1123 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1124 return EGL_FALSE;
1125 }
1126
1127 if (surfPtr->GetNativeWindow() == nullptr) {
1128 WLOGE("GetFrameTimestampSupportedANDROID native window is nullptr.");
1129 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1130 return EGL_FALSE;
1131 }
1132 switch (timestamp) {
1133 case EGL_COMPOSITE_DEADLINE_ANDROID:
1134 case EGL_COMPOSITE_INTERVAL_ANDROID:
1135 case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
1136 case EGL_REQUESTED_PRESENT_TIME_ANDROID:
1137 case EGL_RENDERING_COMPLETE_TIME_ANDROID:
1138 case EGL_COMPOSITION_LATCH_TIME_ANDROID:
1139 case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
1140 case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
1141 case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
1142 case EGL_DEQUEUE_READY_TIME_ANDROID:
1143 case EGL_READS_DONE_TIME_ANDROID:
1144 return EGL_TRUE;
1145 default:
1146 return EGL_FALSE;
1147 }
1148 }
1149
PresentationTimeANDROID(EGLSurface surface,EGLnsecsANDROID time)1150 EGLBoolean EglWrapperDisplay::PresentationTimeANDROID(EGLSurface surface, EGLnsecsANDROID time)
1151 {
1152 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1153
1154 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surface);
1155 if (!CheckObject(surfPtr)) {
1156 WLOGE("EGLSurface is invalid.");
1157 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1158 return EGL_FALSE;
1159 }
1160 if (surfPtr->GetNativeWindow() == nullptr) {
1161 WLOGE("PresentationTimeANDROID native window is nullptr.");
1162 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1163 return EGL_FALSE;
1164 }
1165
1166 if (NativeWindowHandleOpt(reinterpret_cast<OHNativeWindow*>(surfPtr->GetNativeWindow()),
1167 SET_UI_TIMESTAMP, time) != 0) {
1168 WLOGE("NativeWindowHandleOpt SET_UI_TIMESTAMP failed.");
1169 return EGL_FALSE;
1170 }
1171 return EGL_TRUE;
1172 }
1173
CreatePlatformWindowSurfaceEXT(EGLConfig config,void * nativeWindow,const EGLint * attribList)1174 EGLSurface EglWrapperDisplay::CreatePlatformWindowSurfaceEXT(EGLConfig config, void *nativeWindow,
1175 const EGLint *attribList)
1176 {
1177 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1178
1179 if (nativeWindow == nullptr) {
1180 WLOGE("CreatePlatformWindowSurfaceEXT nativeWindow is invalid.");
1181 ThreadPrivateDataCtl::SetError(EGL_BAD_NATIVE_WINDOW);
1182 return EGL_NO_SURFACE;
1183 }
1184
1185 EglWrapperDispatchTablePtr table = &gWrapperHook;
1186 if (table->isLoad && table->egl.eglCreatePlatformWindowSurfaceEXT) {
1187 EGLSurface surf = table->egl.eglCreatePlatformWindowSurfaceEXT(
1188 disp_, config, nativeWindow, attribList);
1189 if (surf != EGL_NO_SURFACE) {
1190 return new EglWrapperSurface(this, surf);
1191 } else {
1192 WLOGE("egl.eglCreatePlatformWindowSurfaceEXT error.");
1193 }
1194 } else {
1195 WLOGE("eglCreatePlatformWindowSurfaceEXT is invalid.");
1196 }
1197
1198 return EGL_NO_SURFACE;
1199 }
1200
CreatePlatformPixmapSurfaceEXT(EGLConfig config,void * nativePixmap,const EGLint * attribList)1201 EGLSurface EglWrapperDisplay::CreatePlatformPixmapSurfaceEXT(EGLConfig config, void *nativePixmap,
1202 const EGLint *attribList)
1203 {
1204 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1205
1206 if (nativePixmap == nullptr) {
1207 WLOGE("CreatePlatformPixmapSurfaceEXT nativePixmap is invalid.");
1208 ThreadPrivateDataCtl::SetError(EGL_BAD_NATIVE_WINDOW);
1209 return EGL_NO_SURFACE;
1210 }
1211
1212 EglWrapperDispatchTablePtr table = &gWrapperHook;
1213 if (table->isLoad && table->egl.eglCreatePlatformPixmapSurfaceEXT) {
1214 EGLSurface surf = table->egl.eglCreatePlatformPixmapSurfaceEXT(
1215 disp_, config, nativePixmap, attribList);
1216 if (surf != EGL_NO_SURFACE) {
1217 return new EglWrapperSurface(this, surf);
1218 } else {
1219 WLOGE("egl.eglCreatePlatformPixmapSurfaceEXT error.");
1220 }
1221 } else {
1222 WLOGE("eglCreatePlatformPixmapSurfaceEXT is invalid.");
1223 }
1224 return EGL_NO_SURFACE;
1225 }
1226
SwapBuffersWithDamageEXT(EGLSurface surface,const EGLint * rects,EGLint nRects)1227 EGLBoolean EglWrapperDisplay::SwapBuffersWithDamageEXT(EGLSurface surface, const EGLint *rects, EGLint nRects)
1228 {
1229 std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1230
1231 EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surface);
1232 if (!CheckObject(surfPtr)) {
1233 WLOGE("EGLSurface is invalid.");
1234 ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1235 return EGL_FALSE;
1236 }
1237
1238 if (nRects < 0 || (nRects > 0 && rects == nullptr)) {
1239 WLOGE("Paramter error.");
1240 ThreadPrivateDataCtl::SetError(EGL_BAD_PARAMETER);
1241 return EGL_FALSE;
1242 }
1243
1244 EGLBoolean ret = EGL_FALSE;
1245 EglWrapperDispatchTablePtr table = &gWrapperHook;
1246 if (table->isLoad && table->egl.eglSwapBuffersWithDamageEXT) {
1247 ret = table->egl.eglSwapBuffersWithDamageEXT(
1248 disp_, surfPtr->GetEglSurface(), rects, nRects);
1249 } else {
1250 WLOGE("eglSwapBuffersWithDamageEXT is invalid.");
1251 }
1252 return ret;
1253 }
1254 } // namespace OHOS
1255