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             WLOGI("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 
CreateEglSurface(EGLConfig config,NativeWindowType window,const EGLint * attribList)485 EGLSurface EglWrapperDisplay::CreateEglSurface(EGLConfig config, NativeWindowType window, const EGLint *attribList)
486 {
487     WLOGD("");
488     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
489 
490     if (!window) {
491         WLOGE("NativeWindowType window is invalid.");
492         ThreadPrivateDataCtl::SetError(EGL_BAD_NATIVE_WINDOW);
493         return EGL_NO_SURFACE;
494     }
495 
496     EglWrapperDispatchTablePtr table = &gWrapperHook;
497     if (table->isLoad && table->egl.eglCreateWindowSurface) {
498         EGLSurface surf = table->egl.eglCreateWindowSurface(disp_, config, window, attribList);
499         if (surf != EGL_NO_SURFACE) {
500             return new EglWrapperSurface(this, surf, window);
501         } else {
502             WLOGE("egl.eglCreateWindowSurface error.");
503         }
504     } else {
505         WLOGE("eglCreateWindowSurface is invalid.");
506     }
507 
508     return EGL_NO_SURFACE;
509 }
510 
DestroyEglSurface(EGLSurface surf)511 EGLBoolean EglWrapperDisplay::DestroyEglSurface(EGLSurface surf)
512 {
513     WLOGD("");
514     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
515 
516     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
517     if (!CheckObject(surfPtr)) {
518         WLOGE("EGLSurface is invalid.");
519         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
520         return EGL_FALSE;
521     }
522     EGLSurface sur = surfPtr->GetEglSurface();
523 
524     EGLBoolean ret = EGL_FALSE;
525     EglWrapperDispatchTablePtr table = &gWrapperHook;
526     if (table->isLoad && table->egl.eglDestroySurface) {
527         ret = table->egl.eglDestroySurface(disp_, sur);
528         if (ret == EGL_TRUE) {
529             surfPtr->Destroy();
530         } else {
531             WLOGE("eglDestroySurface error.");
532         }
533     } else {
534         WLOGE("eglDestroySurface is invalid.");
535     }
536 
537     return ret;
538 }
539 
AddObject(EglWrapperObject * obj)540 void EglWrapperDisplay::AddObject(EglWrapperObject *obj)
541 {
542     std::lock_guard<std::mutex> lock(lockMutex_);
543     objects_.insert(obj);
544 }
545 
RemoveObject(EglWrapperObject * obj)546 void EglWrapperDisplay::RemoveObject(EglWrapperObject *obj)
547 {
548     std::lock_guard<std::mutex> lock(lockMutex_);
549     objects_.erase(obj);
550 }
551 
ClearObjects()552 void EglWrapperDisplay::ClearObjects()
553 {
554     std::lock_guard<std::mutex> lock(lockMutex_);
555     for (auto obj : objects_) {
556         obj->Release();
557     }
558     objects_.clear();
559 }
560 
CheckObject(EglWrapperObject * obj)561 bool EglWrapperDisplay::CheckObject(EglWrapperObject *obj)
562 {
563     std::lock_guard<std::mutex> lock(lockMutex_);
564     if (objects_.find(obj) != objects_.end()) {
565         if (obj->GetDisplay() == this) {
566             return true;
567         }
568     }
569     return false;
570 }
571 
CopyBuffers(EGLSurface surf,NativePixmapType target)572 EGLBoolean EglWrapperDisplay::CopyBuffers(EGLSurface surf, NativePixmapType target)
573 {
574     WLOGD("");
575     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
576 
577     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
578     if (!CheckObject(surfPtr)) {
579         WLOGE("EGLSurface is invalid.");
580         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
581         return EGL_FALSE;
582     }
583 
584     EGLBoolean ret = EGL_FALSE;
585     EglWrapperDispatchTablePtr table = &gWrapperHook;
586     if (table->isLoad && table->egl.eglCopyBuffers) {
587         ret = table->egl.eglCopyBuffers(disp_, surfPtr->GetEglSurface(), target);
588     } else {
589         WLOGE("eglCopyBuffers is invalid.");
590     }
591 
592     return ret;
593 }
594 
CreatePbufferSurface(EGLConfig config,const EGLint * attribList)595 EGLSurface EglWrapperDisplay::CreatePbufferSurface(EGLConfig config, const EGLint *attribList)
596 {
597     WLOGD("");
598     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
599 
600     EglWrapperDispatchTablePtr table = &gWrapperHook;
601     if (table->isLoad && table->egl.eglCreatePbufferSurface) {
602         EGLSurface surf = table->egl.eglCreatePbufferSurface(disp_, config, attribList);
603         if (surf != EGL_NO_SURFACE) {
604             return new EglWrapperSurface(this, surf);
605         } else {
606             WLOGE("egl.eglCreatePbufferSurface error.");
607         }
608     } else {
609         WLOGE("eglCreatePbufferSurface is invalid.");
610     }
611 
612     return EGL_NO_SURFACE;
613 }
614 
CreatePixmapSurface(EGLConfig config,EGLNativePixmapType pixmap,const EGLint * attribList)615 EGLSurface EglWrapperDisplay::CreatePixmapSurface(EGLConfig config,
616     EGLNativePixmapType pixmap, const EGLint* attribList)
617 {
618     WLOGD("");
619     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
620 
621     EglWrapperDispatchTablePtr table = &gWrapperHook;
622     if (table->isLoad && table->egl.eglCreatePixmapSurface) {
623         EGLSurface surf = table->egl.eglCreatePixmapSurface(disp_, config, pixmap, attribList);
624         if (surf != EGL_NO_SURFACE) {
625             return new EglWrapperSurface(this, surf);
626         } else {
627             WLOGE("egl.eglCreatePixmapSurface error.");
628         }
629     } else {
630         WLOGE("eglCreatePixmapSurface is invalid.");
631     }
632 
633     return EGL_NO_SURFACE;
634 }
635 
QueryContext(EGLContext ctx,EGLint attribute,EGLint * value)636 EGLBoolean EglWrapperDisplay::QueryContext(EGLContext ctx, EGLint attribute, EGLint *value)
637 {
638     WLOGD("");
639     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
640 
641     EglWrapperContext *ctxPtr = EglWrapperContext::GetWrapperContext(ctx);
642     if (!CheckObject(ctxPtr)) {
643         WLOGE("EGLContext is invalid.");
644         ThreadPrivateDataCtl::SetError(EGL_BAD_CONTEXT);
645         return EGL_FALSE;
646     }
647 
648     EGLBoolean ret = EGL_FALSE;
649     EglWrapperDispatchTablePtr table = &gWrapperHook;
650     if (table->isLoad && table->egl.eglQueryContext) {
651         ret = table->egl.eglQueryContext(disp_,
652             ctxPtr->GetEglContext(), attribute, value);
653     } else {
654         WLOGE("eglQueryContext is invalid.");
655     }
656 
657     return ret;
658 }
659 
QuerySurface(EGLSurface surf,EGLint attribute,EGLint * value)660 EGLBoolean EglWrapperDisplay::QuerySurface(EGLSurface surf, EGLint attribute, EGLint *value)
661 {
662     WLOGD("");
663     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
664 
665     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
666     if (!CheckObject(surfPtr)) {
667         WLOGE("EGLSurface is invalid.");
668         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
669         return EGL_FALSE;
670     }
671 
672     EGLBoolean ret = EGL_FALSE;
673     EglWrapperDispatchTablePtr table = &gWrapperHook;
674     if (table->isLoad && table->egl.eglQuerySurface) {
675         ret = table->egl.eglQuerySurface(disp_,
676             surfPtr->GetEglSurface(), attribute, value);
677     } else {
678         WLOGE("eglQuerySurface is invalid.");
679     }
680 
681     return ret;
682 }
683 
SwapBuffers(EGLSurface surf)684 EGLBoolean EglWrapperDisplay::SwapBuffers(EGLSurface surf)
685 {
686     WLOGD("");
687     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
688 
689     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
690     if (!CheckObject(surfPtr)) {
691         if (surfPtr != nullptr && surfPtr->GetEglSurface() == nullptr) {
692             WLOGE("INparament is invalid.");
693             return EGL_FALSE;
694         }
695         WLOGE("EGLSurface is invalid.");
696         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
697         return EGL_FALSE;
698     }
699 
700     EGLBoolean ret = EGL_FALSE;
701     EglWrapperDispatchTablePtr table = &gWrapperHook;
702     if (table->isLoad && table->egl.eglSwapBuffers) {
703         ret = table->egl.eglSwapBuffers(disp_, surfPtr->GetEglSurface());
704     } else {
705         WLOGE("eglSwapBuffers is invalid.");
706     }
707 
708     return ret;
709 }
710 
BindTexImage(EGLSurface surf,EGLint buffer)711 EGLBoolean EglWrapperDisplay::BindTexImage(EGLSurface surf, EGLint buffer)
712 {
713     WLOGD("");
714     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
715 
716     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
717     if (!CheckObject(surfPtr)) {
718         WLOGE("EGLSurface is invalid.");
719         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
720         return EGL_FALSE;
721     }
722 
723     EGLBoolean ret = EGL_FALSE;
724     EglWrapperDispatchTablePtr table = &gWrapperHook;
725     if (table->isLoad && table->egl.eglBindTexImage) {
726         ret = table->egl.eglBindTexImage(disp_, surfPtr->GetEglSurface(), buffer);
727     } else {
728         WLOGE("eglBindTexImage is invalid.");
729     }
730 
731     return ret;
732 }
733 
ReleaseTexImage(EGLSurface surf,EGLint buffer)734 EGLBoolean EglWrapperDisplay::ReleaseTexImage(EGLSurface surf, EGLint buffer)
735 {
736     WLOGD("");
737     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
738 
739     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
740     if (!CheckObject(surfPtr)) {
741         WLOGE("EGLSurface is invalid.");
742         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
743         return EGL_FALSE;
744     }
745 
746     EGLBoolean ret = EGL_FALSE;
747     EglWrapperDispatchTablePtr table = &gWrapperHook;
748     if (table->isLoad && table->egl.eglReleaseTexImage) {
749         ret = table->egl.eglReleaseTexImage(disp_, surfPtr->GetEglSurface(), buffer);
750     } else {
751         WLOGE("eglReleaseTexImage is invalid.");
752     }
753 
754     return ret;
755 }
756 
SurfaceAttrib(EGLSurface surf,EGLint attribute,EGLint value)757 EGLBoolean EglWrapperDisplay::SurfaceAttrib(EGLSurface surf, EGLint attribute, EGLint value)
758 {
759     WLOGD("");
760     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
761 
762     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
763     if (!CheckObject(surfPtr)) {
764         WLOGE("EGLSurface is invalid.");
765         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
766         return EGL_FALSE;
767     }
768 
769     EGLBoolean ret = EGL_FALSE;
770     EglWrapperDispatchTablePtr table = &gWrapperHook;
771     if (table->isLoad && table->egl.eglSurfaceAttrib) {
772         ret = table->egl.eglSurfaceAttrib(disp_,
773             surfPtr->GetEglSurface(), attribute, value);
774     } else {
775         WLOGE("eglSurfaceAttrib is invalid.");
776     }
777 
778     return ret;
779 }
780 
CreatePbufferFromClientBuffer(EGLenum buftype,EGLClientBuffer buffer,EGLConfig config,const EGLint * attribList)781 EGLSurface EglWrapperDisplay::CreatePbufferFromClientBuffer(
782     EGLenum buftype, EGLClientBuffer buffer,
783     EGLConfig config, const EGLint *attribList)
784 {
785     WLOGD("");
786     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
787 
788     EglWrapperDispatchTablePtr table = &gWrapperHook;
789     if (table->isLoad && table->egl.eglCreatePbufferFromClientBuffer) {
790         EGLSurface surf = table->egl.eglCreatePbufferFromClientBuffer(
791             disp_, buftype, buffer, config, attribList);
792         if (surf != EGL_NO_SURFACE) {
793             return new EglWrapperSurface(this, surf);
794         } else {
795             WLOGE("egl.eglCreatePbufferFromClientBuffer error.");
796         }
797     } else {
798         WLOGE("eglCreatePbufferFromClientBuffer is invalid.");
799     }
800 
801     return EGL_NO_SURFACE;
802 }
803 
CreateImage(EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLAttrib * attribList)804 EGLImage EglWrapperDisplay::CreateImage(EGLContext ctx, EGLenum target,
805     EGLClientBuffer buffer, const EGLAttrib *attribList)
806 {
807     WLOGD("");
808     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
809 
810     EGLContext actualCtx  = EGL_NO_CONTEXT;
811     if (ctx != EGL_NO_CONTEXT) {
812         EglWrapperContext *ctxPtr = EglWrapperContext::GetWrapperContext(ctx);
813         if (CheckObject(ctxPtr)) {
814             actualCtx = ctxPtr->GetEglContext();
815         }
816     }
817 
818     EglWrapperDispatchTablePtr table = &gWrapperHook;
819     if (table->isLoad && table->egl.eglCreateImage) {
820         return table->egl.eglCreateImage(disp_, actualCtx, target, buffer, attribList);
821     } else {
822         WLOGE("eglCreateImage is invalid.");
823     }
824 
825     return EGL_NO_IMAGE_KHR;
826 }
827 
DestroyImage(EGLImage img)828 EGLBoolean EglWrapperDisplay::DestroyImage(EGLImage img)
829 {
830     WLOGD("");
831     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
832 
833     EGLBoolean ret = EGL_FALSE;
834     EglWrapperDispatchTablePtr table = &gWrapperHook;
835     if (table->isLoad && table->egl.eglDestroyImage) {
836         ret = table->egl.eglDestroyImage(disp_, img);
837     } else {
838         WLOGE("eglDestroyImage is invalid.");
839     }
840 
841     return ret;
842 }
843 
CreatePlatformWindowSurface(EGLConfig config,void * nativeWindow,const EGLAttrib * attribList)844 EGLSurface EglWrapperDisplay::CreatePlatformWindowSurface(EGLConfig config,
845     void *nativeWindow, const EGLAttrib *attribList)
846 {
847     WLOGD("");
848     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
849 
850     if (!nativeWindow) {
851         WLOGE("nativeWindow is invalid.");
852         ThreadPrivateDataCtl::SetError(EGL_BAD_NATIVE_WINDOW);
853         return EGL_NO_SURFACE;
854     }
855 
856     EglWrapperDispatchTablePtr table = &gWrapperHook;
857     if (table->isLoad && table->egl.eglCreatePlatformWindowSurface) {
858         EGLSurface surf = table->egl.eglCreatePlatformWindowSurface(disp_,
859             config, nativeWindow, attribList);
860         if (surf != EGL_NO_SURFACE) {
861             return new EglWrapperSurface(this, surf);
862         } else {
863             WLOGE("egl.eglCreatePlatformWindowSurface error.");
864         }
865     } else {
866         WLOGE("eglCreatePlatformWindowSurface is invalid.");
867     }
868 
869     return EGL_NO_SURFACE;
870 }
871 
CreatePlatformPixmapSurface(EGLConfig config,void * nativePixmap,const EGLAttrib * attribList)872 EGLSurface EglWrapperDisplay::CreatePlatformPixmapSurface(EGLConfig config,
873     void *nativePixmap, const EGLAttrib *attribList)
874 {
875     WLOGD("");
876     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
877 
878     if (!nativePixmap) {
879         WLOGE("nativePixmap is invalid.");
880         ThreadPrivateDataCtl::SetError(EGL_BAD_NATIVE_WINDOW);
881         return EGL_NO_SURFACE;
882     }
883 
884     EglWrapperDispatchTablePtr table = &gWrapperHook;
885     if (table->isLoad && table->egl.eglCreatePlatformPixmapSurface) {
886         EGLSurface surf = table->egl.eglCreatePlatformPixmapSurface(disp_,
887             config, nativePixmap, attribList);
888         if (surf != EGL_NO_SURFACE) {
889             return new EglWrapperSurface(this, surf);
890         } else {
891             WLOGE("egl.eglCreatePlatformPixmapSurface error.");
892         }
893     } else {
894         WLOGE("eglCreatePlatformPixmapSurface is invalid.");
895     }
896 
897     return EGL_NO_SURFACE;
898 }
899 
LockSurfaceKHR(EGLSurface surf,const EGLint * attribList)900 EGLBoolean EglWrapperDisplay::LockSurfaceKHR(EGLSurface surf, const EGLint *attribList)
901 {
902     WLOGD("");
903     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
904 
905     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
906     if (!CheckObject(surfPtr)) {
907         WLOGE("EGLSurface is invalid.");
908         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
909         return EGL_FALSE;
910     }
911 
912     EGLBoolean ret = EGL_FALSE;
913     EglWrapperDispatchTablePtr table = &gWrapperHook;
914     if (table->isLoad && table->egl.eglLockSurfaceKHR) {
915         ret = table->egl.eglLockSurfaceKHR(disp_,
916             surfPtr->GetEglSurface(), attribList);
917     } else {
918         WLOGE("eglLockSurfaceKHR is invalid.");
919     }
920 
921     return ret;
922 }
923 
UnlockSurfaceKHR(EGLSurface surf)924 EGLBoolean EglWrapperDisplay::UnlockSurfaceKHR(EGLSurface surf)
925 {
926     WLOGD("");
927     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
928 
929     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
930     if (!CheckObject(surfPtr)) {
931         WLOGE("EGLSurface is invalid.");
932         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
933         return EGL_FALSE;
934     }
935 
936     EGLBoolean ret = EGL_FALSE;
937     EglWrapperDispatchTablePtr table = &gWrapperHook;
938     if (table->isLoad && table->egl.eglUnlockSurfaceKHR) {
939         ret = table->egl.eglUnlockSurfaceKHR(disp_, surfPtr->GetEglSurface());
940     } else {
941         WLOGE("eglUnlockSurfaceKHR is invalid.");
942     }
943 
944     return ret;
945 }
946 
CreateImageKHR(EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLint * attribList)947 EGLImageKHR EglWrapperDisplay::CreateImageKHR(EGLContext ctx, EGLenum target,
948     EGLClientBuffer buffer, const EGLint *attribList)
949 {
950     WLOGD("");
951     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
952 
953     EGLContext actualCtx  = EGL_NO_CONTEXT;
954     if (ctx != EGL_NO_CONTEXT) {
955         EglWrapperContext *ctxPtr = EglWrapperContext::GetWrapperContext(ctx);
956         if (CheckObject(ctxPtr)) {
957             actualCtx = ctxPtr->GetEglContext();
958         }
959     }
960 
961     EglWrapperDispatchTablePtr table = &gWrapperHook;
962     if (table->isLoad && table->egl.eglCreateImageKHR) {
963         return table->egl.eglCreateImageKHR(disp_, actualCtx, target, buffer, attribList);
964     } else {
965         WLOGE("eglCreateImageKHR is invalid.");
966     }
967 
968     return EGL_NO_IMAGE_KHR;
969 }
970 
DestroyImageKHR(EGLImageKHR img)971 EGLBoolean EglWrapperDisplay::DestroyImageKHR(EGLImageKHR img)
972 {
973     WLOGD("");
974     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
975 
976     EGLBoolean ret = EGL_FALSE;
977     EglWrapperDispatchTablePtr table = &gWrapperHook;
978     if (table->isLoad && table->egl.eglDestroyImageKHR) {
979         ret = table->egl.eglDestroyImageKHR(disp_, img);
980     } else {
981         WLOGE("eglDestroyImageKHR is invalid.");
982     }
983 
984     return ret;
985 }
986 
CreateStreamProducerSurfaceKHR(EGLConfig config,EGLStreamKHR stream,const EGLint * attribList)987 EGLSurface EglWrapperDisplay::CreateStreamProducerSurfaceKHR(EGLConfig config,
988     EGLStreamKHR stream, const EGLint *attribList)
989 {
990     WLOGD("");
991     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
992 
993     EglWrapperDispatchTablePtr table = &gWrapperHook;
994     if (table->isLoad && table->egl.eglCreateStreamProducerSurfaceKHR) {
995         EGLSurface surf = table->egl.eglCreateStreamProducerSurfaceKHR(
996             disp_, config, stream, attribList);
997         if (surf != EGL_NO_SURFACE) {
998             return new EglWrapperSurface(this, surf);
999         } else {
1000             WLOGE("egl.eglCreateStreamProducerSurfaceKHR error.");
1001         }
1002     } else {
1003         WLOGE("eglCreateStreamProducerSurfaceKHR is invalid.");
1004     }
1005 
1006     return EGL_NO_SURFACE;
1007 }
1008 
SwapBuffersWithDamageKHR(EGLSurface draw,EGLint * rects,EGLint nRects)1009 EGLBoolean EglWrapperDisplay::SwapBuffersWithDamageKHR(EGLSurface draw, EGLint *rects, EGLint nRects)
1010 {
1011     WLOGD("");
1012     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1013 
1014     EglWrapperSurface *surfacePtr = EglWrapperSurface::GetWrapperSurface(draw);
1015     if (!CheckObject(surfacePtr)) {
1016         WLOGE("EGLSurface is invalid.");
1017         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1018         return EGL_FALSE;
1019     }
1020 
1021     if (nRects < 0 || (nRects > 0 && rects == NULL)) {
1022         WLOGE("Paramter error.");
1023         ThreadPrivateDataCtl::SetError(EGL_BAD_PARAMETER);
1024         return EGL_FALSE;
1025     }
1026 
1027     EGLBoolean ret = EGL_FALSE;
1028     EglWrapperDispatchTablePtr table = &gWrapperHook;
1029     if (table->isLoad && table->egl.eglSwapBuffersWithDamageKHR) {
1030         ret = table->egl.eglSwapBuffersWithDamageKHR(
1031             disp_, surfacePtr->GetEglSurface(), rects, nRects);
1032     } else {
1033         WLOGE("eglSwapBuffersWithDamageKHR is invalid.");
1034     }
1035 
1036     return ret;
1037 }
1038 
SetDamageRegionKHR(EGLSurface surf,EGLint * rects,EGLint nRects)1039 EGLBoolean EglWrapperDisplay::SetDamageRegionKHR(EGLSurface surf, EGLint *rects, EGLint nRects)
1040 {
1041     WLOGD("");
1042     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1043 
1044     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surf);
1045     if (!CheckObject(surfPtr)) {
1046         WLOGE("EGLSurface is invalid.");
1047         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1048         return EGL_FALSE;
1049     }
1050 
1051     if (nRects < 0 || (nRects > 0 && rects == nullptr)) {
1052         WLOGE("Paramter error.");
1053         ThreadPrivateDataCtl::SetError(EGL_BAD_PARAMETER);
1054         return EGL_FALSE;
1055     }
1056 
1057     EGLBoolean ret = EGL_FALSE;
1058     EglWrapperDispatchTablePtr table = &gWrapperHook;
1059     if (table->isLoad && table->egl.eglSetDamageRegionKHR) {
1060         ret = table->egl.eglSetDamageRegionKHR(
1061             disp_, surfPtr->GetEglSurface(), rects, nRects);
1062     } else {
1063         WLOGE("eglSetDamageRegionKHR is invalid.");
1064     }
1065 
1066     return ret;
1067 }
1068 
GetCompositorTimingSupportedANDROID(EGLSurface surface,EGLint name)1069 EGLBoolean EglWrapperDisplay::GetCompositorTimingSupportedANDROID(EGLSurface surface, EGLint name)
1070 {
1071     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1072 
1073     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surface);
1074     if (!CheckObject(surfPtr)) {
1075         WLOGE("EGLSurface is invalid.");
1076         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1077         return EGL_FALSE;
1078     }
1079 
1080     if (surfPtr->GetNativeWindow() == nullptr) {
1081         WLOGE("GetCompositorTimingSupportedANDROID native window is nullptr.");
1082         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1083         return EGL_FALSE;
1084     }
1085 
1086     switch (name) {
1087         case EGL_COMPOSITE_DEADLINE_ANDROID:
1088         case EGL_COMPOSITE_INTERVAL_ANDROID:
1089         case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
1090             return EGL_TRUE;
1091         default:
1092             return EGL_FALSE;
1093     }
1094 }
1095 
GetFrameTimestampSupportedANDROID(EGLSurface surface,EGLint timestamp)1096 EGLBoolean EglWrapperDisplay::GetFrameTimestampSupportedANDROID(EGLSurface surface, EGLint timestamp)
1097 {
1098     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1099 
1100     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surface);
1101     if (!CheckObject(surfPtr)) {
1102         WLOGE("EGLSurface is invalid.");
1103         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1104         return EGL_FALSE;
1105     }
1106 
1107     if (surfPtr->GetNativeWindow() == nullptr) {
1108         WLOGE("GetFrameTimestampSupportedANDROID native window is nullptr.");
1109         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1110         return EGL_FALSE;
1111     }
1112     switch (timestamp) {
1113         case EGL_COMPOSITE_DEADLINE_ANDROID:
1114         case EGL_COMPOSITE_INTERVAL_ANDROID:
1115         case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
1116         case EGL_REQUESTED_PRESENT_TIME_ANDROID:
1117         case EGL_RENDERING_COMPLETE_TIME_ANDROID:
1118         case EGL_COMPOSITION_LATCH_TIME_ANDROID:
1119         case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
1120         case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
1121         case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
1122         case EGL_DEQUEUE_READY_TIME_ANDROID:
1123         case EGL_READS_DONE_TIME_ANDROID:
1124             return EGL_TRUE;
1125         default:
1126             return EGL_FALSE;
1127     }
1128 }
1129 
PresentationTimeANDROID(EGLSurface surface,EGLnsecsANDROID time)1130 EGLBoolean EglWrapperDisplay::PresentationTimeANDROID(EGLSurface surface, EGLnsecsANDROID time)
1131 {
1132     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1133 
1134     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surface);
1135     if (!CheckObject(surfPtr)) {
1136         WLOGE("EGLSurface is invalid.");
1137         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1138         return EGL_FALSE;
1139     }
1140     if (surfPtr->GetNativeWindow() == nullptr) {
1141         WLOGE("PresentationTimeANDROID native window is nullptr.");
1142         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1143         return EGL_FALSE;
1144     }
1145 
1146     if (NativeWindowHandleOpt(reinterpret_cast<OHNativeWindow*>(surfPtr->GetNativeWindow()),
1147         SET_UI_TIMESTAMP, time) != 0) {
1148         WLOGE("NativeWindowHandleOpt SET_UI_TIMESTAMP failed.");
1149         return EGL_FALSE;
1150     }
1151     return EGL_TRUE;
1152 }
1153 
CreatePlatformWindowSurfaceEXT(EGLConfig config,void * nativeWindow,const EGLint * attribList)1154 EGLSurface EglWrapperDisplay::CreatePlatformWindowSurfaceEXT(EGLConfig config, void *nativeWindow,
1155     const EGLint *attribList)
1156 {
1157     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1158 
1159     if (nativeWindow == nullptr) {
1160         WLOGE("CreatePlatformWindowSurfaceEXT nativeWindow is invalid.");
1161         ThreadPrivateDataCtl::SetError(EGL_BAD_NATIVE_WINDOW);
1162         return EGL_NO_SURFACE;
1163     }
1164 
1165     EglWrapperDispatchTablePtr table = &gWrapperHook;
1166     if (table->isLoad && table->egl.eglCreatePlatformWindowSurfaceEXT) {
1167         EGLSurface surf = table->egl.eglCreatePlatformWindowSurfaceEXT(
1168             disp_, config, nativeWindow, attribList);
1169         if (surf != EGL_NO_SURFACE) {
1170             return new EglWrapperSurface(this, surf);
1171         } else {
1172             WLOGE("egl.eglCreatePlatformWindowSurfaceEXT error.");
1173         }
1174     } else {
1175         WLOGE("eglCreatePlatformWindowSurfaceEXT is invalid.");
1176     }
1177 
1178     return EGL_NO_SURFACE;
1179 }
1180 
CreatePlatformPixmapSurfaceEXT(EGLConfig config,void * nativePixmap,const EGLint * attribList)1181 EGLSurface EglWrapperDisplay::CreatePlatformPixmapSurfaceEXT(EGLConfig config, void *nativePixmap,
1182     const EGLint *attribList)
1183 {
1184     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1185 
1186     if (nativePixmap == nullptr) {
1187         WLOGE("CreatePlatformPixmapSurfaceEXT nativePixmap is invalid.");
1188         ThreadPrivateDataCtl::SetError(EGL_BAD_NATIVE_WINDOW);
1189         return EGL_NO_SURFACE;
1190     }
1191 
1192     EglWrapperDispatchTablePtr table = &gWrapperHook;
1193     if (table->isLoad && table->egl.eglCreatePlatformPixmapSurfaceEXT) {
1194         EGLSurface surf = table->egl.eglCreatePlatformPixmapSurfaceEXT(
1195             disp_, config, nativePixmap, attribList);
1196         if (surf != EGL_NO_SURFACE) {
1197             return new EglWrapperSurface(this, surf);
1198         } else {
1199             WLOGE("egl.eglCreatePlatformPixmapSurfaceEXT error.");
1200         }
1201     } else {
1202         WLOGE("eglCreatePlatformPixmapSurfaceEXT is invalid.");
1203     }
1204     return EGL_NO_SURFACE;
1205 }
1206 
SwapBuffersWithDamageEXT(EGLSurface surface,const EGLint * rects,EGLint nRects)1207 EGLBoolean EglWrapperDisplay::SwapBuffersWithDamageEXT(EGLSurface surface, const EGLint *rects, EGLint nRects)
1208 {
1209     std::lock_guard<std::recursive_mutex> lock(refLockMutex_);
1210 
1211     EglWrapperSurface *surfPtr = EglWrapperSurface::GetWrapperSurface(surface);
1212     if (!CheckObject(surfPtr)) {
1213         WLOGE("EGLSurface is invalid.");
1214         ThreadPrivateDataCtl::SetError(EGL_BAD_SURFACE);
1215         return EGL_FALSE;
1216     }
1217 
1218     if (nRects < 0 || (nRects > 0 && rects == nullptr)) {
1219         WLOGE("Paramter error.");
1220         ThreadPrivateDataCtl::SetError(EGL_BAD_PARAMETER);
1221         return EGL_FALSE;
1222     }
1223 
1224     EGLBoolean ret = EGL_FALSE;
1225     EglWrapperDispatchTablePtr table = &gWrapperHook;
1226     if (table->isLoad && table->egl.eglSwapBuffersWithDamageEXT) {
1227         ret = table->egl.eglSwapBuffersWithDamageEXT(
1228             disp_, surfPtr->GetEglSurface(), rects, nRects);
1229     } else {
1230         WLOGE("eglSwapBuffersWithDamageEXT is invalid.");
1231     }
1232     return ret;
1233 }
1234 } // namespace OHOS
1235