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 <external_window.h>
17
18 #include "gles/device_gles.h"
19 #include "gles/egl_functions.h"
20 #include "gles/gl_functions.h"
21 #include "gles/gpu_buffer_gles.h"
22 #include "gles/gpu_image_gles.h"
23 #include "util/log.h"
24
RENDER_BEGIN_NAMESPACE()25 RENDER_BEGIN_NAMESPACE()
26 BASE_NS::unique_ptr<GpuImage> DeviceGLES::CreateGpuImageView(
27 const GpuImageDesc& desc, const BackendSpecificImageDesc& platformData)
28 {
29 BASE_NS::unique_ptr<GpuImage> image;
30 PLUGIN_ASSERT(IsActive());
31 GpuImagePlatformDataGL data {};
32 #if RENDER_HAS_GLES_BACKEND
33 if (backendType_ == DeviceBackendType::OPENGLES) {
34 const ImageDescGLES& tmp = (const ImageDescGLES&)platformData;
35 data.type = tmp.type;
36 data.image = tmp.image;
37 data.bytesperpixel = tmp.bytesperpixel;
38 data.dataType = tmp.dataType;
39 data.format = tmp.format;
40 data.internalFormat = tmp.internalFormat;
41 data.eglImage = tmp.eglImage;
42 data.hwBuffer = tmp.platformHwBuffer;
43 data.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
44
45 if (!data.hwBuffer) {
46 image = CreateGpuImageView(desc, data);
47 } else if (eglCreateImageKHR && eglDestroyImageKHR) {
48 auto* nativeBufferPtr = reinterpret_cast<OH_NativeBuffer*>(tmp.platformHwBuffer);
49 auto nativeWindowBufferPtr = OH_NativeWindow_CreateNativeWindowBufferFromNativeBuffer(nativeBufferPtr);
50
51 const auto dsp = static_cast<const DevicePlatformDataGLES&>(eglState_.GetPlatformData()).display;
52 static constexpr EGLint attrs[] = { EGL_IMAGE_PRESERVED, EGL_TRUE, EGL_NONE };
53 const auto eglImage =
54 eglCreateImageKHR(dsp, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS, nativeWindowBufferPtr, attrs);
55 if (!eglImage) {
56 PLUGIN_LOG_E("eglCreateImageKHR failed %d", eglGetError());
57 return {};
58 }
59 GpuImageDesc finalDesc = GetImageDescFromHwBufferDesc(tmp.platformHwBuffer);
60
61 data.type = GL_TEXTURE_EXTERNAL_OES;
62 data.eglImage = reinterpret_cast<uintptr_t>(eglImage);
63 image = CreateGpuImageView(finalDesc, data);
64
65 eglDestroyImageKHR(dsp, eglImage);
66 OH_NativeWindow_DestroyNativeWindowBuffer(nativeWindowBufferPtr);
67 }
68 }
69 #endif
70 #if RENDER_HAS_GL_BACKEND
71 if (backendType_ == DeviceBackendType::OPENGL) {
72 const ImageDescGL& tmp = (const ImageDescGL&)platformData;
73 data.type = tmp.type;
74 data.image = tmp.image;
75 data.bytesperpixel = tmp.bytesperpixel;
76 data.dataType = tmp.dataType;
77 data.format = tmp.format;
78 data.internalFormat = tmp.internalFormat;
79 data.swizzle = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA };
80 image = CreateGpuImageView(desc, data);
81 }
82 #endif
83 return image;
84 }
85
CreateGpuBuffer(const BackendSpecificBufferDesc & desc)86 BASE_NS::unique_ptr<GpuBuffer> DeviceGLES::CreateGpuBuffer(const BackendSpecificBufferDesc& desc)
87 {
88 PLUGIN_ASSERT(IsActive());
89 #if RENDER_HAS_GLES_BACKEND
90 if (backendType_ == DeviceBackendType::OPENGLES) {
91 if (!glBufferStorageExternalEXT) {
92 return {};
93 }
94 const auto& tmp = static_cast<const BufferDescGLES&>(desc);
95 if (!tmp.platformHwBuffer) {
96 return {};
97 }
98
99 auto* nativeBufferPtr = reinterpret_cast<OH_NativeBuffer*>(tmp.platformHwBuffer);
100 auto nativeWindowBufferPtr = OH_NativeWindow_CreateNativeWindowBufferFromNativeBuffer(nativeBufferPtr);
101 if (!nativeWindowBufferPtr) {
102 PLUGIN_LOG_E("OH_NativeWindow_CreateNativeWindowBufferFromNativeBuffer failed %d", eglGetError());
103 return {};
104 }
105
106 const GpuBufferDesc finalDesc = GetBufferDescFromHwBufferDesc(tmp.platformHwBuffer);
107 GpuBufferPlatformDataGL platformData {};
108 platformData.alignedBindByteSize = finalDesc.byteSize;
109 platformData.alignedByteSize = finalDesc.byteSize;
110 platformData.bindMemoryByteSize = finalDesc.byteSize;
111 platformData.eglClientBuffer = reinterpret_cast<uintptr_t>(nativeWindowBufferPtr);
112 auto buffer = BASE_NS::make_unique<GpuBufferGLES>(*this, finalDesc, platformData);
113 OH_NativeWindow_DestroyNativeWindowBuffer(nativeWindowBufferPtr);
114 return buffer;
115 }
116 #endif
117 #if RENDER_HAS_GL_BACKEND
118 if (backendType_ == DeviceBackendType::OPENGL) {
119 }
120 #endif
121 return {};
122 }
123 RENDER_END_NAMESPACE()
124