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