1 /*
2 * Copyright (c) 2021 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 #define GL_GLEXT_PROTOTYPES
17 #define EGL_EGLEXT_PROTOTYPES
18
19 #include "surface_image.h"
20
21 #include "securec.h"
22 #include "sandbox_utils.h"
23 #include "surface_utils.h"
24
25 #include <cinttypes>
26 #include <atomic>
27 #include "metadata_helper.h"
28 #include <sync_fence.h>
29 #include <unistd.h>
30 #include <window.h>
31
32 #include <EGL/egl.h>
33 #include <EGL/eglext.h>
34 #include <GLES/gl.h>
35 #include <GLES/glext.h>
36
37 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
38
39 namespace OHOS {
40 namespace {
41 // Get a uniqueID in a process
GetProcessUniqueId()42 static int GetProcessUniqueId()
43 {
44 static std::atomic<int> g_counter { 0 };
45 return g_counter.fetch_add(1);
46 }
47 }
48
SurfaceImage(uint32_t textureId,uint32_t textureTarget)49 SurfaceImage::SurfaceImage(uint32_t textureId, uint32_t textureTarget)
50 : ConsumerSurface("SurfaceImage-" + std::to_string(GetRealPid()) + "-" + std::to_string(GetProcessUniqueId())),
51 textureId_(textureId),
52 textureTarget_(textureTarget),
53 updateSurfaceImage_(false),
54 eglDisplay_(EGL_NO_DISPLAY),
55 eglContext_(EGL_NO_CONTEXT),
56 currentSurfaceImage_(UINT_MAX),
57 currentSurfaceBuffer_(nullptr),
58 currentTimeStamp_(0)
59 {
60 InitSurfaceImage();
61 }
62
SurfaceImage()63 SurfaceImage::SurfaceImage()
64 : ConsumerSurface("SurfaceImageConsumer-" + std::to_string(GetRealPid()) +
65 "-" + std::to_string(GetProcessUniqueId())),
66 currentSurfaceBuffer_(nullptr),
67 currentTimeStamp_(0)
68 {
69 InitSurfaceImage();
70 }
71
~SurfaceImage()72 SurfaceImage::~SurfaceImage()
73 {
74 for (auto it = imageCacheSeqs_.begin(); it != imageCacheSeqs_.end(); it++) {
75 DestroyEGLImage(it->second.eglImage_);
76 DestroyEGLSync(it->second.eglSync_);
77 }
78 }
79
InitSurfaceImage()80 void SurfaceImage::InitSurfaceImage()
81 {
82 std::string name = "SurfaceImage-" + std::to_string(GetRealPid()) + "-" + std::to_string(GetProcessUniqueId());
83 auto ret = ConsumerSurface::Init();
84 uniqueId_ = GetUniqueId();
85 BLOGI("InitSurfaceImage Init ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, uniqueId_);
86 surfaceImageName_ = name;
87 }
88
UpdateBasicInfo(const sptr<SurfaceBuffer> & buffer,int64_t timestamp)89 void SurfaceImage::UpdateBasicInfo(const sptr<SurfaceBuffer>& buffer, int64_t timestamp)
90 {
91 currentSurfaceBuffer_ = buffer;
92 currentTimeStamp_ = timestamp;
93 preBufferProperties_ = bufferProperties_;
94 bufferProperties_ = {
95 GetBufferCropRegion(buffer),
96 ConsumerSurface::GetTransform(),
97 buffer->GetWidth(),
98 buffer->GetHeight()
99 };
100 }
101
UpdateSurfaceInfo(sptr<SurfaceBuffer> buffer,const sptr<SyncFence> & acquireFence,int64_t timestamp,const Rect & damage)102 void SurfaceImage::UpdateSurfaceInfo(sptr<SurfaceBuffer> buffer, const sptr<SyncFence> &acquireFence,
103 int64_t timestamp, const Rect& damage)
104 {
105 // release old buffer
106 int releaseFence = -1;
107 auto iter = imageCacheSeqs_.find(currentSurfaceImage_);
108 if (iter != imageCacheSeqs_.end() && iter->second.eglSync_ != EGL_NO_SYNC_KHR) {
109 // PLANNING: use eglDupNativeFenceFDOHOS in the future.
110 releaseFence = eglDupNativeFenceFDANDROID(eglDisplay_, iter->second.eglSync_);
111 }
112 // There is no need to close this fd, because in function ReleaseBuffer it will be closed.
113 ReleaseBuffer(currentSurfaceBuffer_, releaseFence);
114
115 currentSurfaceImage_ = buffer->GetSeqNum();
116 UpdateBasicInfo(buffer, timestamp);
117
118 auto utils = SurfaceUtils::GetInstance();
119 utils->ComputeTransformMatrix(currentTransformMatrix_, TRANSFORM_MATRIX_ELE_COUNT,
120 currentSurfaceBuffer_, bufferProperties_.transformType, damage);
121 utils->ComputeTransformMatrixV2(currentTransformMatrixV2_, TRANSFORM_MATRIX_ELE_COUNT,
122 currentSurfaceBuffer_, bufferProperties_.transformType, damage);
123 if (preBufferProperties_ != bufferProperties_) {
124 utils->ComputeBufferMatrix(currentBufferMatrix_, TRANSFORM_MATRIX_ELE_COUNT,
125 currentSurfaceBuffer_, bufferProperties_.transformType, bufferProperties_.crop);
126 }
127
128 // wait on this acquireFence.
129 if (acquireFence != nullptr) {
130 acquireFence->Wait(-1);
131 }
132 }
133
GetBufferCropRegion(const sptr<OHOS::SurfaceBuffer> & buffer)134 Rect SurfaceImage::GetBufferCropRegion(const sptr<OHOS::SurfaceBuffer>& buffer)
135 {
136 BufferHandleMetaRegion cropRegion{0, 0, 0, 0};
137
138 if (MetadataHelper::GetCropRectMetadata(buffer, cropRegion) == GSERROR_OK) {
139 BLOGD("GetCropRectMetadata success,"
140 "left: %{public}d, top: %{public}d, width: %{public}d, height: %{public}d",
141 cropRegion.left, cropRegion.top, cropRegion.width, cropRegion.height);
142 return {cropRegion.left, cropRegion.top, cropRegion.width, cropRegion.height};
143 }
144
145 return {0, 0, buffer->GetWidth(), buffer->GetHeight()};
146 }
147
UpdateSurfaceImage()148 SurfaceError SurfaceImage::UpdateSurfaceImage()
149 {
150 std::lock_guard<std::mutex> lockGuard(opMutex_);
151
152 // validate egl state
153 SurfaceError ret = ValidateEglState();
154 if (ret != SURFACE_ERROR_OK) {
155 return ret;
156 }
157
158 // acquire buffer
159 sptr<SurfaceBuffer> buffer = nullptr;
160 sptr<SyncFence> acquireFence = SyncFence::InvalidFence();
161 int64_t timestamp;
162 Rect damage;
163 ret = AcquireBuffer(buffer, acquireFence, timestamp, damage);
164 if (ret != SURFACE_ERROR_OK) {
165 return ret;
166 }
167
168 ret = UpdateEGLImageAndTexture(buffer);
169 if (ret != SURFACE_ERROR_OK) {
170 ReleaseBuffer(buffer, -1);
171 return ret;
172 }
173
174 UpdateSurfaceInfo(buffer, acquireFence, timestamp, damage);
175 return SURFACE_ERROR_OK;
176 }
177
AttachContext(uint32_t textureId)178 SurfaceError SurfaceImage::AttachContext(uint32_t textureId)
179 {
180 std::lock_guard<std::mutex> lockGuard(opMutex_);
181 // validate egl state
182 SurfaceError ret = ValidateEglState();
183 if (ret != SURFACE_ERROR_OK) {
184 return ret;
185 }
186
187 textureId_ = textureId;
188 auto iter = imageCacheSeqs_.find(currentSurfaceImage_);
189 if (iter != imageCacheSeqs_.end()) {
190 glBindTexture(textureTarget_, textureId);
191 GLenum error = glGetError();
192 if (error != GL_NO_ERROR) {
193 BLOGE("glBindTexture failed, textureTarget:%{public}d, textureId_:%{public}d, error:%{public}d,"
194 "uniqueId: %{public}" PRIu64 ".", textureTarget_, textureId_, error, uniqueId_);
195 return SURFACE_ERROR_EGL_API_FAILED;
196 }
197 glEGLImageTargetTexture2DOES(textureTarget_, static_cast<GLeglImageOES>(iter->second.eglImage_));
198 error = glGetError();
199 if (error != GL_NO_ERROR) {
200 BLOGE("glEGLImageTargetTexture2DOES failed, textureTarget:%{public}d, error:%{public}d"
201 "uniqueId: %{public}" PRIu64 ".", textureTarget_, error, uniqueId_);
202 return SURFACE_ERROR_EGL_API_FAILED;
203 }
204 }
205
206 // If there is no EGLImage, we cannot simply return an error.
207 // Developers can call OH_NativeImage_UpdateSurfaceImage later to achieve their purpose.
208 return SURFACE_ERROR_OK;
209 }
210
DetachContext()211 SurfaceError SurfaceImage::DetachContext()
212 {
213 std::lock_guard<std::mutex> lockGuard(opMutex_);
214 // validate egl state
215 SurfaceError ret = ValidateEglState();
216 if (ret != SURFACE_ERROR_OK) {
217 return ret;
218 }
219
220 textureId_ = 0;
221 glBindTexture(textureTarget_, 0);
222 GLenum error = glGetError();
223 if (error != GL_NO_ERROR) {
224 BLOGE("glBindTexture failed, textureTarget:%{public}d, textureId:%{public}d, error:%{public}d"
225 "uniqueId: %{public}" PRIu64 ".", textureTarget_, textureId_, error, uniqueId_);
226 return SURFACE_ERROR_EGL_API_FAILED;
227 }
228 return SURFACE_ERROR_OK;
229 }
230
GetTimeStamp()231 int64_t SurfaceImage::GetTimeStamp()
232 {
233 std::lock_guard<std::mutex> lockGuard(opMutex_);
234 return currentTimeStamp_;
235 }
236
GetTransformMatrix(float matrix[TRANSFORM_MATRIX_ELE_COUNT])237 SurfaceError SurfaceImage::GetTransformMatrix(float matrix[TRANSFORM_MATRIX_ELE_COUNT])
238 {
239 std::lock_guard<std::mutex> lockGuard(opMutex_);
240 auto ret = memcpy_s(matrix, sizeof(float) * TRANSFORM_MATRIX_ELE_COUNT,
241 currentTransformMatrix_, sizeof(currentTransformMatrix_));
242 if (ret != EOK) {
243 BLOGE("memcpy_s failed ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, uniqueId_);
244 return SURFACE_ERROR_UNKOWN;
245 }
246 return SURFACE_ERROR_OK;
247 }
248
GetTransformMatrixV2(float matrix[TRANSFORM_MATRIX_ELE_COUNT])249 SurfaceError SurfaceImage::GetTransformMatrixV2(float matrix[TRANSFORM_MATRIX_ELE_COUNT])
250 {
251 std::lock_guard<std::mutex> lockGuard(opMutex_);
252 auto ret = memcpy_s(matrix, sizeof(float) * TRANSFORM_MATRIX_ELE_COUNT,
253 currentTransformMatrixV2_, sizeof(currentTransformMatrixV2_));
254 if (ret != EOK) {
255 BLOGE("memcpy_s failed ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, uniqueId_);
256 return SURFACE_ERROR_UNKOWN;
257 }
258 return SURFACE_ERROR_OK;
259 }
260
GetBufferMatrix(float matrix[TRANSFORM_MATRIX_ELE_COUNT])261 SurfaceError SurfaceImage::GetBufferMatrix(float matrix[TRANSFORM_MATRIX_ELE_COUNT])
262 {
263 std::lock_guard<std::mutex> lockGuard(opMutex_);
264 auto ret = memcpy_s(matrix, sizeof(float) * TRANSFORM_MATRIX_ELE_COUNT,
265 currentBufferMatrix_, sizeof(currentBufferMatrix_));
266 if (ret != EOK) {
267 BLOGE("memcpy_s failed ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, uniqueId_);
268 return SURFACE_ERROR_MEM_OPERATION_ERROR;
269 }
270 return SURFACE_ERROR_OK;
271 }
272
ValidateEglState()273 SurfaceError SurfaceImage::ValidateEglState()
274 {
275 EGLDisplay disp = eglGetCurrentDisplay();
276 EGLContext context = eglGetCurrentContext();
277
278 if ((eglDisplay_ != disp && eglDisplay_ != EGL_NO_DISPLAY) || (disp == EGL_NO_DISPLAY)) {
279 BLOGE("EGLDisplay is invalid, errno : 0x%{public}x, uniqueId: %{public}" PRIu64 ".",
280 eglGetError(), uniqueId_);
281 return SURFACE_ERROR_EGL_STATE_UNKONW;
282 }
283 if ((eglContext_ != context && eglContext_ != EGL_NO_CONTEXT) || (context == EGL_NO_CONTEXT)) {
284 BLOGE("EGLContext is invalid, errno : 0x%{public}x, uniqueId: %{public}" PRIu64 ".",
285 eglGetError(), uniqueId_);
286 return SURFACE_ERROR_EGL_STATE_UNKONW;
287 }
288
289 eglDisplay_ = disp;
290 eglContext_ = context;
291 return SURFACE_ERROR_OK;
292 }
293
CreateEGLImage(EGLDisplay disp,const sptr<SurfaceBuffer> & buffer)294 EGLImageKHR SurfaceImage::CreateEGLImage(EGLDisplay disp, const sptr<SurfaceBuffer>& buffer)
295 {
296 sptr<SurfaceBuffer> bufferImpl = buffer;
297 NativeWindowBuffer* nBuffer = CreateNativeWindowBufferFromSurfaceBuffer(&bufferImpl);
298 EGLint attrs[] = {
299 EGL_IMAGE_PRESERVED,
300 EGL_TRUE,
301 EGL_NONE,
302 };
303
304 EGLImageKHR img = eglCreateImageKHR(disp, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS, nBuffer, attrs);
305 if (img == EGL_NO_IMAGE_KHR) {
306 EGLint error = eglGetError();
307 BLOGE("failed, error %{public}d, uniqueId: %{public}" PRIu64 ".", error, uniqueId_);
308 eglTerminate(disp);
309 }
310 DestroyNativeWindowBuffer(nBuffer);
311 return img;
312 }
313
CheckImageCacheNeedClean(uint32_t seqNum)314 void SurfaceImage::CheckImageCacheNeedClean(uint32_t seqNum)
315 {
316 for (auto it = imageCacheSeqs_.begin(); it != imageCacheSeqs_.end();) {
317 bool result = true;
318 if (seqNum == it->first) {
319 it++;
320 continue;
321 }
322 if (IsSurfaceBufferInCache(it->first, result) == SURFACE_ERROR_OK && !result) {
323 DestroyEGLImage(it->second.eglImage_);
324 DestroyEGLSync(it->second.eglSync_);
325 it = imageCacheSeqs_.erase(it);
326 } else {
327 it++;
328 }
329 }
330 }
331
DestroyEGLImage(EGLImageKHR & eglImage)332 void SurfaceImage::DestroyEGLImage(EGLImageKHR &eglImage)
333 {
334 if (eglImage != EGL_NO_IMAGE_KHR) {
335 eglDestroyImageKHR(eglDisplay_, eglImage);
336 eglImage = EGL_NO_IMAGE_KHR;
337 }
338 }
339
DestroyEGLSync(EGLSyncKHR & eglSync)340 void SurfaceImage::DestroyEGLSync(EGLSyncKHR &eglSync)
341 {
342 if (eglSync != EGL_NO_SYNC_KHR) {
343 eglDestroySyncKHR(eglDisplay_, eglSync);
344 eglSync = EGL_NO_SYNC_KHR;
345 }
346 }
347
DestroyEGLImageBySeq(uint32_t seqNum)348 void SurfaceImage::DestroyEGLImageBySeq(uint32_t seqNum)
349 {
350 auto iter = imageCacheSeqs_.find(seqNum);
351 if (iter != imageCacheSeqs_.end()) {
352 DestroyEGLImage(iter->second.eglImage_);
353 }
354 imageCacheSeqs_.erase(seqNum);
355 }
356
NewBufferDestroyEGLImage(bool isNewBuffer,uint32_t seqNum)357 void SurfaceImage::NewBufferDestroyEGLImage(bool isNewBuffer, uint32_t seqNum)
358 {
359 if (isNewBuffer) {
360 DestroyEGLImageBySeq(seqNum);
361 }
362 }
363
UpdateEGLImageAndTexture(const sptr<SurfaceBuffer> & buffer)364 SurfaceError SurfaceImage::UpdateEGLImageAndTexture(const sptr<SurfaceBuffer>& buffer)
365 {
366 bool isNewBuffer = false;
367 // private function, buffer is always valid.
368 uint32_t seqNum = buffer->GetSeqNum();
369 // If there was no eglImage binding to this buffer, we create a new one.
370 if (imageCacheSeqs_.find(seqNum) == imageCacheSeqs_.end()) {
371 isNewBuffer = true;
372 EGLImageKHR eglImage = CreateEGLImage(eglDisplay_, buffer);
373 if (eglImage == EGL_NO_IMAGE_KHR) {
374 return SURFACE_ERROR_EGL_API_FAILED;
375 }
376 imageCacheSeqs_[seqNum].eglImage_ = eglImage;
377 }
378
379 auto &image = imageCacheSeqs_[seqNum];
380 glBindTexture(textureTarget_, textureId_);
381 GLenum error = glGetError();
382 if (error != GL_NO_ERROR) {
383 NewBufferDestroyEGLImage(isNewBuffer, seqNum);
384 BLOGE("glBindTexture failed, textureTarget:%{public}d, textureId_:%{public}d, error:%{public}d"
385 "uniqueId: %{public}" PRIu64 ".", textureTarget_, textureId_, error, uniqueId_);
386 return SURFACE_ERROR_EGL_API_FAILED;
387 }
388 glEGLImageTargetTexture2DOES(textureTarget_, static_cast<GLeglImageOES>(image.eglImage_));
389 error = glGetError();
390 if (error != GL_NO_ERROR) {
391 NewBufferDestroyEGLImage(isNewBuffer, seqNum);
392 BLOGE("glEGLImageTargetTexture2DOES failed, textureTarget:%{public}d, error:%{public}d"
393 "uniqueId: %{public}" PRIu64 ".", textureTarget_, error, uniqueId_);
394 return SURFACE_ERROR_EGL_API_FAILED;
395 }
396
397 // Create fence object for current image
398 auto iter = imageCacheSeqs_.find(currentSurfaceImage_);
399 if (iter != imageCacheSeqs_.end()) {
400 auto ¤tImage = iter->second;
401 auto preSync = currentImage.eglSync_;
402 if (preSync != EGL_NO_SYNC_KHR) {
403 eglDestroySyncKHR(eglDisplay_, preSync);
404 }
405 currentImage.eglSync_ = eglCreateSyncKHR(eglDisplay_, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
406 glFlush();
407 }
408
409 if (isNewBuffer) {
410 CheckImageCacheNeedClean(seqNum);
411 }
412 return SURFACE_ERROR_OK;
413 }
414
SetOnBufferAvailableListener(void * context,OnBufferAvailableListener listener)415 SurfaceError SurfaceImage::SetOnBufferAvailableListener(void *context, OnBufferAvailableListener listener)
416 {
417 std::lock_guard<std::mutex> lockGuard(opMutex_);
418 if (listener == nullptr) {
419 BLOGE("listener is nullptr, uniqueId: %{public}" PRIu64 ".", uniqueId_);
420 return SURFACE_ERROR_INVALID_PARAM;
421 }
422
423 listener_ = listener;
424 context_ = context;
425 return SURFACE_ERROR_OK;
426 }
427
UnsetOnBufferAvailableListener()428 SurfaceError SurfaceImage::UnsetOnBufferAvailableListener()
429 {
430 std::lock_guard<std::mutex> lockGuard(opMutex_);
431 listener_ = nullptr;
432 context_ = nullptr;
433 return SURFACE_ERROR_OK;
434 }
435
~SurfaceImageListener()436 SurfaceImageListener::~SurfaceImageListener()
437 {
438 BLOGE("~SurfaceImageListener");
439 surfaceImage_ = nullptr;
440 }
441
OnBufferAvailable()442 void SurfaceImageListener::OnBufferAvailable()
443 {
444 BLOGD("enter OnBufferAvailable");
445 auto surfaceImage = surfaceImage_.promote();
446 if (surfaceImage == nullptr) {
447 BLOGE("surfaceImage promote failed");
448 return;
449 }
450
451 // check here maybe a messagequeue, flag instead now
452 surfaceImage->OnUpdateBufferAvailableState(true);
453 if (surfaceImage->listener_ != nullptr) {
454 surfaceImage->listener_(surfaceImage->context_);
455 }
456 }
457
AcquireNativeWindowBuffer(OHNativeWindowBuffer ** nativeWindowBuffer,int32_t * fenceFd)458 SurfaceError SurfaceImage::AcquireNativeWindowBuffer(OHNativeWindowBuffer** nativeWindowBuffer, int32_t* fenceFd)
459 {
460 std::lock_guard<std::mutex> lockGuard(opMutex_);
461 sptr<SurfaceBuffer> buffer = nullptr;
462 sptr<SyncFence> acquireFence = SyncFence::InvalidFence();
463 int64_t timestamp;
464 Rect damage;
465 SurfaceError ret = AcquireBuffer(buffer, acquireFence, timestamp, damage);
466 if (ret != SURFACE_ERROR_OK) {
467 BLOGE("AcquireBuffer failed: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, uniqueId_);
468 return ret;
469 }
470
471 UpdateBasicInfo(buffer, timestamp);
472
473 auto utils = SurfaceUtils::GetInstance();
474 utils->ComputeTransformMatrixV2(currentTransformMatrixV2_, TRANSFORM_MATRIX_ELE_COUNT,
475 currentSurfaceBuffer_, bufferProperties_.transformType, damage);
476 if (bufferProperties_ != preBufferProperties_) {
477 utils->ComputeBufferMatrix(currentBufferMatrix_, TRANSFORM_MATRIX_ELE_COUNT,
478 currentSurfaceBuffer_, bufferProperties_.transformType, bufferProperties_.crop);
479 }
480 *fenceFd = acquireFence->Dup();
481 OHNativeWindowBuffer *nwBuffer = new OHNativeWindowBuffer();
482 nwBuffer->sfbuffer = buffer;
483 NativeObjectReference(nwBuffer);
484 *nativeWindowBuffer = nwBuffer;
485
486 return SURFACE_ERROR_OK;
487 }
488
ReleaseNativeWindowBuffer(OHNativeWindowBuffer * nativeWindowBuffer,int32_t fenceFd)489 SurfaceError SurfaceImage::ReleaseNativeWindowBuffer(OHNativeWindowBuffer* nativeWindowBuffer, int32_t fenceFd)
490 {
491 std::lock_guard<std::mutex> lockGuard(opMutex_);
492 // There is no need to close this fd, because in function ReleaseBuffer it will be closed.
493 SurfaceError ret = ReleaseBuffer(nativeWindowBuffer->sfbuffer, fenceFd);
494 if (ret != SURFACE_ERROR_OK) {
495 BLOGE("ReleaseBuffer failed: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, uniqueId_);
496 return ret;
497 }
498 NativeObjectUnreference(nativeWindowBuffer);
499 return SURFACE_ERROR_OK;
500 }
501
SetDefaultUsage(uint64_t usage)502 SurfaceError SurfaceImage::SetDefaultUsage(uint64_t usage)
503 {
504 SurfaceError ret = ConsumerSurface::SetDefaultUsage(usage);
505 if (ret != SURFACE_ERROR_OK) {
506 BLOGE("SetDefaultUsage failed: %{public}d, uniqueId: %{public}" PRIu64 ", usage: %{public}" PRIu64 ".", ret,
507 uniqueId_, usage);
508 }
509 return ret;
510 }
511
SetDefaultSize(int32_t width,int32_t height)512 SurfaceError SurfaceImage::SetDefaultSize(int32_t width, int32_t height)
513 {
514 SurfaceError ret = SetDefaultWidthAndHeight(width, height);
515 if (ret != SURFACE_ERROR_OK) {
516 BLOGE("SetDefaultWidthAndHeight failed: %{public}d, uniqueId: %{public}" PRIu64 ", width: %{public}d, "
517 "height: %{public}d", ret, uniqueId_, width, height);
518 }
519 return ret;
520 }
521 } // namespace OHOS
522