• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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