1 /*
2 * Copyright (c) 2024 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 "ohos_native_buffer_adapter_impl.h"
17 #include "surface_buffer_impl.h"
18 #include "nweb_log.h"
19
20 #include <EGL/egl.h>
21 #include <EGL/eglext.h>
22 #include <GLES3/gl3.h>
23
24 namespace OHOS::NWeb {
25
GetInstance()26 OhosNativeBufferAdapter& OhosNativeBufferAdapterImpl::GetInstance()
27 {
28 WVLOG_D("Native buffer adapter impl get instance.");
29 static OhosNativeBufferAdapterImpl instance;
30 return instance;
31 }
32
OhosNativeBufferAdapterImpl()33 OhosNativeBufferAdapterImpl::OhosNativeBufferAdapterImpl()
34 {
35 WVLOG_D("Native buffer adapter impl constructor.");
36 }
37
~OhosNativeBufferAdapterImpl()38 OhosNativeBufferAdapterImpl::~OhosNativeBufferAdapterImpl()
39 {
40 WVLOG_D("Native buffer adapter impl destructor.");
41 }
42
IsBufferLocked(OH_NativeBuffer * buffer) const43 bool OhosNativeBufferAdapterImpl::IsBufferLocked(OH_NativeBuffer* buffer) const
44 {
45 if (buffer == nullptr) {
46 return false;
47 }
48 auto it = lockedBuffers_.find(buffer);
49 bool result = (it != lockedBuffers_.end() && it->second);
50 WVLOG_D("Native buffer is locked: %{public}s", result ? "yes" : "no");
51 return result;
52 }
53
AcquireBuffer(void * buffer)54 void OhosNativeBufferAdapterImpl::AcquireBuffer(void* buffer)
55 {
56 if (buffer == nullptr) {
57 WVLOG_E("native buffer acquire, buffer is null.");
58 return;
59 }
60 WVLOG_D("native buffer acquired buffer %{private}p.", buffer);
61 OH_NativeBuffer_Reference(static_cast<OH_NativeBuffer*>(buffer));
62 }
63
Release(void * buffer)64 void OhosNativeBufferAdapterImpl::Release(void* buffer)
65 {
66 if (buffer == nullptr) {
67 WVLOG_E("native buffer release, buffer is null.");
68 return;
69 }
70
71 WVLOG_D("native buffer release buffer %{private}p.", buffer);
72 if (OH_NativeBuffer_Unreference(static_cast<OH_NativeBuffer*>(buffer)) == 0) {
73 WVLOG_D("native buffer release, unreference buffer.");
74 }
75
76 buffer = nullptr;
77 }
78
GetEGLBuffer(void * buffer,void ** eglBuffer)79 int OhosNativeBufferAdapterImpl::GetEGLBuffer(void* buffer, void** eglBuffer)
80 {
81 if (buffer == nullptr) {
82 WVLOG_E("native buffer get egl buffer, buffer is null.");
83 return -1;
84 }
85 WVLOG_D("native buffer GetEGLBuffer %{private}p.", buffer);
86
87 OHNativeWindowBuffer* nativeWindowBuffer =
88 OH_NativeWindow_CreateNativeWindowBufferFromNativeBuffer(static_cast<OH_NativeBuffer*>(buffer));
89 if (nativeWindowBuffer == nullptr) {
90 WVLOG_E("native buffer failed to create native window buffer from native buffer.");
91 return -1;
92 } else {
93 WVLOG_D("native buffer create native window buffer from native bufferL %{private}p.", *eglBuffer);
94 *eglBuffer = nativeWindowBuffer;
95 return 0;
96 }
97 }
98
FreeEGLBuffer(void * eglBuffer)99 int OhosNativeBufferAdapterImpl::FreeEGLBuffer(void* eglBuffer)
100 {
101 if (eglBuffer == nullptr) {
102 WVLOG_E("native buffer free EGLBuffer is null.");
103 return -1;
104 }
105
106 WVLOG_D("native buffer free EGLBuffer %{private}p", eglBuffer);
107 OH_NativeWindow_NativeObjectUnreference(eglBuffer);
108 return 0;
109 }
110
NativeBufferFromNativeWindowBuffer(void * nativeWindowBuffer,void ** nativeBuffer)111 int OhosNativeBufferAdapterImpl::NativeBufferFromNativeWindowBuffer(void* nativeWindowBuffer, void** nativeBuffer)
112 {
113 if (nativeWindowBuffer == nullptr) {
114 WVLOG_E("native buffer NativeBufferFromNativeWindowBuffer, native window buffer is null.");
115 return -1;
116 }
117
118 *nativeBuffer = OH_NativeBufferFromNativeWindowBuffer(static_cast<NativeWindowBuffer*>(nativeWindowBuffer));
119 if (*nativeBuffer == nullptr) {
120 WVLOG_E("native buffer NativeBufferFromNativeWindowBuffer, native buffer is null.");
121 return -1;
122 }
123 WVLOG_D("native buffer NativeBufferFromNativeWindowBuffer %{private}p", nativeWindowBuffer);
124 return 0;
125 }
126
GetSeqNum(void * nativeBuffer)127 uint32_t OhosNativeBufferAdapterImpl::GetSeqNum(void* nativeBuffer)
128 {
129 if (nativeBuffer == nullptr) {
130 WVLOG_E("native buffer GetSeqNum, nativeBuffer is null.");
131 return 0;
132 }
133 SurfaceBufferImpl* buffer = reinterpret_cast<SurfaceBufferImpl *>(nativeBuffer);
134 return buffer->GetSeqNum();
135 }
136
Allocate(const std::shared_ptr<NativeBufferConfigAdapter> bufferConfig,void ** outBuffer)137 void OhosNativeBufferAdapterImpl::Allocate(
138 const std::shared_ptr<NativeBufferConfigAdapter> bufferConfig, void** outBuffer)
139 {
140 if (bufferConfig == nullptr) {
141 return;
142 }
143 int width = bufferConfig->GetBufferWidth();
144 int height = bufferConfig->GetBufferHeight();
145 int usage = bufferConfig->GetBufferUsage();
146 OH_NativeBuffer_Config config = {
147 .width = width,
148 .height = height,
149 .format = OH_NativeBuffer_Format::NATIVEBUFFER_PIXEL_FMT_RGBA_8888,
150 .usage = usage,
151 };
152
153 // create a new OH_NativeBuffer using the OHOS native buffer allocation function
154 // The plan here is that the actual buffer holder will be held onto by chromium.
155 OH_NativeBuffer* buffer = OH_NativeBuffer_Alloc(&config);
156 if (buffer != nullptr) {
157 WVLOG_D("native buffer allocate success, rawbuffer stored %{private}p", buffer);
158 *outBuffer = buffer;
159 } else {
160 WVLOG_E("native buffer allocate failed.");
161 *outBuffer = nullptr;
162 }
163 }
164
Describe(std::shared_ptr<NativeBufferConfigAdapter> bufferConfig,void * buffer)165 void OhosNativeBufferAdapterImpl::Describe(std::shared_ptr<NativeBufferConfigAdapter> bufferConfig, void* buffer)
166 {
167 if (buffer == nullptr) {
168 WVLOG_E("native buffer describe, buffer is null.");
169 return;
170 }
171 WVLOG_D("native buffer describe buffer %{private}p.", buffer);
172
173 OH_NativeBuffer_Config config = {};
174 OH_NativeBuffer_GetConfig(static_cast<OH_NativeBuffer*>(buffer), &config);
175
176 bufferConfig->SetBufferWidth(config.width);
177 bufferConfig->SetBufferHeight(config.height);
178 bufferConfig->SetBufferFormat(config.format);
179 bufferConfig->SetBufferUsage(config.usage);
180 bufferConfig->SetBufferStride(config.stride);
181
182 return;
183 }
184
Lock(void * buffer,uint64_t usage,int32_t fence,void ** out_virtual_address)185 int OhosNativeBufferAdapterImpl::Lock(void* buffer, uint64_t usage, int32_t fence, void** out_virtual_address)
186 {
187 WVLOG_D("native buffer waiting for lock.");
188 if (buffer == nullptr) {
189 WVLOG_E("native buffer lock, buffer is null.");
190 return -1;
191 }
192
193 if (IsBufferLocked(static_cast<OH_NativeBuffer*>(buffer))) {
194 WVLOG_D("native buffer lock - buffer already locked.");
195 return -1;
196 }
197
198 lockedBuffers_[static_cast<OH_NativeBuffer*>(buffer)] = true;
199
200 return OH_NativeBuffer_Map(static_cast<OH_NativeBuffer*>(buffer), out_virtual_address);
201 }
202
RecvHandleFromUnixSocket(int socketFd,void ** outBuffer)203 int OhosNativeBufferAdapterImpl::RecvHandleFromUnixSocket(int socketFd, void** outBuffer)
204 {
205 WVLOG_D("native buffer receive handle from unix socket.");
206 return 0;
207 }
208
SendHandleToUnixSocket(const void * buffer,int socketFd)209 int OhosNativeBufferAdapterImpl::SendHandleToUnixSocket(const void* buffer, int socketFd)
210 {
211 WVLOG_D("native buffer send handle to unix socket.");
212
213 if (buffer == nullptr) {
214 WVLOG_E("native buffer SendHandleToUnixSocket, buffer is null.");
215 return -1;
216 }
217
218 return 0;
219 }
220
Unlock(void * buffer,int32_t * fence)221 int OhosNativeBufferAdapterImpl::Unlock(void* buffer, int32_t* fence)
222 {
223 WVLOG_D("native buffer waiting for unlock.");
224 if (buffer == nullptr) {
225 WVLOG_E("native buffer lock, buffer is null.");
226 return -1;
227 }
228
229 if (!IsBufferLocked(static_cast<OH_NativeBuffer*>(buffer))) {
230 WVLOG_D("native buffer unlock - buffer is already unlocked.");
231 return -1;
232 }
233
234 int result = OH_NativeBuffer_Unmap(static_cast<OH_NativeBuffer*>(buffer));
235 lockedBuffers_.erase(static_cast<OH_NativeBuffer*>(buffer));
236 return result;
237 }
238
FreeNativeBuffer(void * nativeBuffer)239 int OhosNativeBufferAdapterImpl::FreeNativeBuffer(void* nativeBuffer)
240 {
241 if (nativeBuffer == nullptr) {
242 WVLOG_E("native buffer FreeNativeBuffer, native buffer is null.");
243 return -1;
244 }
245 WVLOG_D("native buffer FreeNativeBuffer freeing: %{private}p.", nativeBuffer);
246 OH_NativeBuffer_Unreference(static_cast<OH_NativeBuffer*>(nativeBuffer));
247 return 0;
248 }
249 } // namespace OHOS::NWeb
250