1/* 2 * Copyright (c) 2021-2023 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 "surface_buffer_impl.h" 17 18#include <mutex> 19 20#include <message_parcel.h> 21#include <parameters.h> 22#include <securec.h> 23#include <sys/mman.h> 24#include "buffer_log.h" 25#include "buffer_extra_data_impl.h" 26#include "v1_1/buffer_handle_meta_key_type.h" 27#include "v1_2/display_buffer_type.h" 28#include "v1_2/include/idisplay_buffer.h" 29 30namespace OHOS { 31namespace { 32using IDisplayBufferSptr = std::shared_ptr<OHOS::HDI::Display::Buffer::V1_2::IDisplayBuffer>; 33static IDisplayBufferSptr g_displayBuffer; 34static std::mutex g_displayBufferMutex; 35class DisplayBufferDiedRecipient : public OHOS::IRemoteObject::DeathRecipient { 36public: 37 DisplayBufferDiedRecipient() = default; 38 virtual ~DisplayBufferDiedRecipient() = default; 39 void OnRemoteDied(const OHOS::wptr<OHOS::IRemoteObject>& remote) override 40 { 41 std::lock_guard<std::mutex> bufferLock(g_displayBufferMutex); 42 g_displayBuffer = nullptr; 43 BLOGD("IDisplayBuffer died and g_displayBuffer is nullptr"); 44 }; 45}; 46 47IDisplayBufferSptr GetDisplayBuffer() 48{ 49 std::lock_guard<std::mutex> bufferLock(g_displayBufferMutex); 50 if (g_displayBuffer != nullptr) { 51 return g_displayBuffer; 52 } 53 return nullptr; 54} 55 56IDisplayBufferSptr GetOrResetDisplayBuffer() 57{ 58 std::lock_guard<std::mutex> bufferLock(g_displayBufferMutex); 59 if (g_displayBuffer != nullptr) { 60 return g_displayBuffer; 61 } 62 63 g_displayBuffer.reset(OHOS::HDI::Display::Buffer::V1_2::IDisplayBuffer::Get()); 64 if (g_displayBuffer == nullptr) { 65 BLOGE("IDisplayBuffer::Get return nullptr."); 66 return nullptr; 67 } 68 sptr<IRemoteObject::DeathRecipient> recipient = new DisplayBufferDiedRecipient(); 69 g_displayBuffer->AddDeathRecipient(recipient); 70 return g_displayBuffer; 71} 72 73constexpr int32_t INVALID_ARGUMENT = -1; 74constexpr uint64_t INVALID_PHYADDR = 0; 75constexpr uint32_t INVALID_SIZE = 0; 76constexpr uint64_t INVALID_USAGE = std::numeric_limits<std::uint64_t>::max(); 77} 78 79sptr<SurfaceBuffer> SurfaceBuffer::Create() 80{ 81 sptr<SurfaceBuffer> surfaceBufferImpl = new SurfaceBufferImpl(); 82 return surfaceBufferImpl; 83} 84 85SurfaceBufferImpl::SurfaceBufferImpl() 86{ 87 { 88 static std::mutex mutex; 89 mutex.lock(); 90 91 static uint32_t sequence_number_ = 0; 92 // 0xFFFF is pid mask. 16 is pid offset. 93 sequenceNumber_ = (static_cast<uint32_t>(getpid()) & 0xFFFF) << 16; 94 // 0xFFFF is seqnum mask. 95 sequenceNumber_ |= (sequence_number_++ & 0xFFFF); 96 97 mutex.unlock(); 98 } 99 metaDataCache_.clear(); 100 bedata_ = new BufferExtraDataImpl; 101 BLOGD("SurfaceBufferImpl ctor, seq: %{public}u", sequenceNumber_); 102} 103 104SurfaceBufferImpl::SurfaceBufferImpl(uint32_t seqNum) 105{ 106 metaDataCache_.clear(); 107 sequenceNumber_ = seqNum; 108 bedata_ = new BufferExtraDataImpl; 109 BLOGD("SurfaceBufferImpl ctor, seq: %{public}u", sequenceNumber_); 110} 111 112SurfaceBufferImpl::~SurfaceBufferImpl() 113{ 114 BLOGD("~SurfaceBufferImpl dtor, seq: %{public}u", sequenceNumber_); 115 FreeBufferHandleLocked(); 116} 117 118bool SurfaceBufferImpl::MetaDataCachedLocked(const uint32_t key, const std::vector<uint8_t>& value) 119{ 120 auto iter = metaDataCache_.find(key); 121 if (iter != metaDataCache_.end() && (*iter).second == value) { 122 return true; 123 } 124 return false; 125} 126 127GSError SurfaceBufferImpl::Alloc(const BufferRequestConfig& config) 128{ 129 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer(); 130 if (displayBuffer == nullptr) { 131 return GSERROR_INTERNAL; 132 } 133 std::lock_guard<std::mutex> lock(mutex_); 134 FreeBufferHandleLocked(); 135 136 GSError ret = CheckBufferConfig(config.width, config.height, config.format, config.usage); 137 if (ret != GSERROR_OK) { 138 return GSERROR_INVALID_ARGUMENTS; 139 } 140 141 OHOS::HDI::Display::Buffer::V1_0::AllocInfo info = {config.width, config.height, config.usage, config.format}; 142 static bool debugHebcDisabled = 143 std::atoi((system::GetParameter("persist.graphic.debug_hebc.disabled", "0")).c_str()) != 0; 144 if (debugHebcDisabled) { 145 info.usage |= (BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA); 146 } 147 auto dRet = displayBuffer->AllocMem(info, handle_); 148 if (dRet == GRAPHIC_DISPLAY_SUCCESS && handle_ != nullptr) { 149 dRet = displayBuffer->RegisterBuffer(*handle_); 150 if (dRet != GRAPHIC_DISPLAY_SUCCESS && dRet != GRAPHIC_DISPLAY_NOT_SUPPORT) { 151 BLOGE("AllocMem RegisterBuffer Failed with %{public}d", dRet); 152 return GSERROR_HDI_ERROR; 153 } 154 surfaceBufferColorGamut_ = static_cast<GraphicColorGamut>(config.colorGamut); 155 transform_ = static_cast<GraphicTransformType>(config.transform); 156 surfaceBufferWidth_ = config.width; 157 surfaceBufferHeight_ = config.height; 158 bufferRequestConfig_ = config; 159 BLOGD("handle w: %{public}d h: %{public}d t: %{public}d, seq: %{public}u", 160 handle_->width, handle_->height, config.transform, sequenceNumber_); 161 return GSERROR_OK; 162 } 163 BLOGW("Alloc Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_); 164 return GSERROR_HDI_ERROR; 165} 166 167GSError SurfaceBufferImpl::Map() 168{ 169 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer(); 170 if (displayBuffer == nullptr) { 171 return GSERROR_INTERNAL; 172 } 173 std::lock_guard<std::mutex> lock(mutex_); 174 if (handle_ == nullptr) { 175 return GSERROR_INVALID_OPERATING; 176 } else if (handle_->virAddr != nullptr) { 177 BLOGD("handle_->virAddr has been maped, seq: %{public}u", sequenceNumber_); 178 return GSERROR_OK; 179 } 180 if (handle_->usage & BUFFER_USAGE_PROTECTED) { 181 BLOGD("usage is BUFFER_USAGE_PROTECTED, do not Map, seq: %{public}u", sequenceNumber_); 182 return GSERROR_OK; 183 } 184 185 void* virAddr = displayBuffer->Mmap(*handle_); 186 if (virAddr == nullptr || virAddr == MAP_FAILED) { 187 return GSERROR_HDI_ERROR; 188 } 189 return GSERROR_OK; 190} 191 192GSError SurfaceBufferImpl::Unmap() 193{ 194 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer(); 195 if (displayBuffer == nullptr) { 196 return GSERROR_INTERNAL; 197 } 198 std::lock_guard<std::mutex> lock(mutex_); 199 if (handle_ == nullptr) { 200 return GSERROR_INVALID_OPERATING; 201 } else if (handle_->virAddr == nullptr) { 202 BLOGW("handle has been unmaped, seq: %{public}u", sequenceNumber_); 203 return GSERROR_OK; 204 } 205 auto dRet = displayBuffer->Unmap(*handle_); 206 if (dRet == GRAPHIC_DISPLAY_SUCCESS) { 207 handle_->virAddr = nullptr; 208 return GSERROR_OK; 209 } 210 BLOGW("Unmap Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_); 211 return GSERROR_HDI_ERROR; 212} 213 214GSError SurfaceBufferImpl::FlushCache() 215{ 216 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer(); 217 if (displayBuffer == nullptr) { 218 return GSERROR_INTERNAL; 219 } 220 221 std::lock_guard<std::mutex> lock(mutex_); 222 if (handle_ == nullptr) { 223 return GSERROR_INVALID_OPERATING; 224 } 225 auto dRet = displayBuffer->FlushCache(*handle_); 226 if (dRet == GRAPHIC_DISPLAY_SUCCESS) { 227 return GSERROR_OK; 228 } 229 BLOGW("FlushCache Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_); 230 return GSERROR_HDI_ERROR; 231} 232 233GSError SurfaceBufferImpl::GetImageLayout(void* layout) 234{ 235 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer(); 236 if (displayBuffer == nullptr) { 237 return GSERROR_INTERNAL; 238 } 239 std::lock_guard<std::mutex> lock(mutex_); 240 if (handle_ == nullptr) { 241 return GSERROR_INVALID_OPERATING; 242 } else if (planesInfo_.planeCount != 0) { 243 return GSERROR_OK; 244 } 245 246 auto dRet = displayBuffer->GetImageLayout(*handle_, 247 *(static_cast<OHOS::HDI::Display::Buffer::V1_2::ImageLayout*>(layout))); 248 if (dRet == GRAPHIC_DISPLAY_SUCCESS) { 249 return GSERROR_OK; 250 } 251 BLOGW("GetImageLayout Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_); 252 return GSERROR_HDI_ERROR; 253} 254 255GSError SurfaceBufferImpl::InvalidateCache() 256{ 257 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer(); 258 if (displayBuffer == nullptr) { 259 return GSERROR_INTERNAL; 260 } 261 std::lock_guard<std::mutex> lock(mutex_); 262 if (handle_ == nullptr) { 263 return GSERROR_INVALID_OPERATING; 264 } 265 266 auto dRet = displayBuffer->InvalidateCache(*handle_); 267 if (dRet == GRAPHIC_DISPLAY_SUCCESS) { 268 return GSERROR_OK; 269 } 270 BLOGW("InvalidateCache Failed with %{public}d, seq: %{public}u", dRet, sequenceNumber_); 271 return GSERROR_HDI_ERROR; 272} 273 274void SurfaceBufferImpl::FreeBufferHandleLocked() 275{ 276 metaDataCache_.clear(); 277 if (handle_) { 278 IDisplayBufferSptr displayBuffer = GetDisplayBuffer(); 279 if (displayBuffer == nullptr) { 280 FreeBufferHandle(handle_); 281 handle_ = nullptr; 282 return; 283 } 284 if (handle_->virAddr != nullptr) { 285 displayBuffer->Unmap(*handle_); 286 handle_->virAddr = nullptr; 287 } 288 displayBuffer->FreeMem(*handle_); 289 handle_ = nullptr; 290 } 291} 292 293// return BufferHandle* is dangerous, need to refactor 294BufferHandle* SurfaceBufferImpl::GetBufferHandle() const 295{ 296 std::lock_guard<std::mutex> lock(mutex_); 297 return handle_; 298} 299 300void SurfaceBufferImpl::SetSurfaceBufferColorGamut(const GraphicColorGamut& colorGamut) 301{ 302 std::lock_guard<std::mutex> lock(mutex_); 303 if (surfaceBufferColorGamut_ != colorGamut) { 304 surfaceBufferColorGamut_ = colorGamut; 305 } 306} 307 308GraphicColorGamut SurfaceBufferImpl::GetSurfaceBufferColorGamut() const 309{ 310 std::lock_guard<std::mutex> lock(mutex_); 311 return surfaceBufferColorGamut_; 312} 313 314void SurfaceBufferImpl::SetSurfaceBufferTransform(const GraphicTransformType& transform) 315{ 316 std::lock_guard<std::mutex> lock(mutex_); 317 if (transform_ != transform) { 318 transform_ = transform; 319 } 320} 321 322GraphicTransformType SurfaceBufferImpl::GetSurfaceBufferTransform() const 323{ 324 std::lock_guard<std::mutex> lock(mutex_); 325 return transform_; 326} 327 328int32_t SurfaceBufferImpl::GetSurfaceBufferWidth() const 329{ 330 std::lock_guard<std::mutex> lock(mutex_); 331 return surfaceBufferWidth_; 332} 333 334int32_t SurfaceBufferImpl::GetSurfaceBufferHeight() const 335{ 336 std::lock_guard<std::mutex> lock(mutex_); 337 return surfaceBufferHeight_; 338} 339 340void SurfaceBufferImpl::SetSurfaceBufferWidth(int32_t width) 341{ 342 std::lock_guard<std::mutex> lock(mutex_); 343 surfaceBufferWidth_ = width; 344} 345 346void SurfaceBufferImpl::SetSurfaceBufferHeight(int32_t height) 347{ 348 std::lock_guard<std::mutex> lock(mutex_); 349 surfaceBufferHeight_ = height; 350} 351 352int32_t SurfaceBufferImpl::GetWidth() const 353{ 354 std::lock_guard<std::mutex> lock(mutex_); 355 if (handle_ == nullptr) { 356 return INVALID_ARGUMENT; 357 } 358 return handle_->width; 359} 360 361int32_t SurfaceBufferImpl::GetHeight() const 362{ 363 std::lock_guard<std::mutex> lock(mutex_); 364 if (handle_ == nullptr) { 365 return INVALID_ARGUMENT; 366 } 367 return handle_->height; 368} 369 370int32_t SurfaceBufferImpl::GetStride() const 371{ 372 std::lock_guard<std::mutex> lock(mutex_); 373 if (handle_ == nullptr) { 374 return INVALID_ARGUMENT; 375 } 376 return handle_->stride; 377} 378 379int32_t SurfaceBufferImpl::GetFormat() const 380{ 381 std::lock_guard<std::mutex> lock(mutex_); 382 if (handle_ == nullptr) { 383 return INVALID_ARGUMENT; 384 } 385 return handle_->format; 386} 387 388uint64_t SurfaceBufferImpl::GetUsage() const 389{ 390 std::lock_guard<std::mutex> lock(mutex_); 391 if (handle_ == nullptr) { 392 return INVALID_USAGE; 393 } 394 return handle_->usage; 395} 396 397uint64_t SurfaceBufferImpl::GetPhyAddr() const 398{ 399 std::lock_guard<std::mutex> lock(mutex_); 400 if (handle_ == nullptr) { 401 return INVALID_PHYADDR; 402 } 403 return handle_->phyAddr; 404} 405 406void* SurfaceBufferImpl::GetVirAddr() 407{ 408 GSError ret = this->Map(); 409 if (ret != GSERROR_OK) { 410 return nullptr; 411 } 412 std::lock_guard<std::mutex> lock(mutex_); 413 if (handle_ == nullptr) { 414 return nullptr; 415 } 416 return handle_->virAddr; 417} 418 419int32_t SurfaceBufferImpl::GetFileDescriptor() const 420{ 421 std::lock_guard<std::mutex> lock(mutex_); 422 if (handle_ == nullptr) { 423 return INVALID_ARGUMENT; 424 } 425 return handle_->fd; 426} 427 428uint32_t SurfaceBufferImpl::GetSize() const 429{ 430 std::lock_guard<std::mutex> lock(mutex_); 431 if (handle_ == nullptr) { 432 return INVALID_SIZE; 433 } 434 return handle_->size; 435} 436 437GSError SurfaceBufferImpl::GetPlanesInfo(void** planesInfo) 438{ 439 if (planesInfo == nullptr) { 440 return GSERROR_INVALID_ARGUMENTS; 441 } 442 OHOS::HDI::Display::Buffer::V1_2::ImageLayout layout; 443 GSError ret = GetImageLayout(&layout); 444 if (ret != GSERROR_OK) { 445 BLOGW("GetImageLayout failed, ret:%d, seq: %{public}u", ret, sequenceNumber_); 446 return ret; 447 } 448 449 std::lock_guard<std::mutex> lock(mutex_); 450 if (planesInfo_.planeCount != 0) { 451 *planesInfo = static_cast<void*>(&planesInfo_); 452 return GSERROR_OK; 453 } 454 planesInfo_.planeCount = layout.planes.size(); 455 for (uint32_t i = 0; i < planesInfo_.planeCount && i < 4; i++) { // 4: max plane count 456 planesInfo_.planes[i].offset = layout.planes[i].offset; 457 planesInfo_.planes[i].rowStride = layout.planes[i].hStride; 458 planesInfo_.planes[i].columnStride = layout.planes[i].vStride; 459 } 460 461 *planesInfo = static_cast<void*>(&planesInfo_); 462 return GSERROR_OK; 463} 464 465void SurfaceBufferImpl::SetExtraData(sptr<BufferExtraData> bedata) 466{ 467 std::lock_guard<std::mutex> lock(mutex_); 468 bedata_ = bedata; 469} 470 471sptr<BufferExtraData> SurfaceBufferImpl::GetExtraData() const 472{ 473 std::lock_guard<std::mutex> lock(mutex_); 474 return bedata_; 475} 476 477void SurfaceBufferImpl::SetBufferHandle(BufferHandle* handle) 478{ 479 if (handle == nullptr) { 480 return; 481 } 482 std::lock_guard<std::mutex> lock(mutex_); 483 if (handle_ == handle) { 484 return; 485 } 486 FreeBufferHandleLocked(); 487 488 handle_ = handle; 489 IDisplayBufferSptr displayBuffer = GetDisplayBuffer(); 490 if (displayBuffer == nullptr) { 491 return; 492 } 493 auto dRet = displayBuffer->RegisterBuffer(*handle_); 494 if (dRet != GRAPHIC_DISPLAY_SUCCESS && dRet != GRAPHIC_DISPLAY_NOT_SUPPORT) { 495 BLOGE("SetBufferHandle RegisterBuffer Failed with %{public}d", dRet); 496 return; 497 } 498} 499 500GSError SurfaceBufferImpl::WriteBufferRequestConfig(MessageParcel& parcel) 501{ 502 std::lock_guard<std::mutex> lock(mutex_); 503 if (!parcel.WriteInt32(bufferRequestConfig_.width) || !parcel.WriteInt32(bufferRequestConfig_.height) || 504 !parcel.WriteInt32(bufferRequestConfig_.strideAlignment) || !parcel.WriteInt32(bufferRequestConfig_.format) || 505 !parcel.WriteUint64(bufferRequestConfig_.usage) || !parcel.WriteInt32(bufferRequestConfig_.timeout) || 506 !parcel.WriteUint32(static_cast<uint32_t>(bufferRequestConfig_.colorGamut)) || 507 !parcel.WriteUint32(static_cast<uint32_t>(bufferRequestConfig_.transform))) { 508 BLOGE("parcel write fail, seq: %{public}u.", sequenceNumber_); 509 return SURFACE_ERROR_UNKOWN; 510 } 511 return GSERROR_OK; 512} 513 514GSError SurfaceBufferImpl::WriteToMessageParcel(MessageParcel& parcel) 515{ 516 std::lock_guard<std::mutex> lock(mutex_); 517 if (handle_ == nullptr) { 518 return GSERROR_NOT_INIT; 519 } 520 bool ret = WriteBufferHandle(parcel, *handle_); 521 if (ret == false) { 522 return GSERROR_API_FAILED; 523 } 524 525 return GSERROR_OK; 526} 527 528GSError SurfaceBufferImpl::ReadBufferRequestConfig(MessageParcel& parcel) 529{ 530 std::lock_guard<std::mutex> lock(mutex_); 531 uint32_t colorGamut = 0; 532 uint32_t transform = 0; 533 if (!parcel.ReadInt32(bufferRequestConfig_.width) || !parcel.ReadInt32(bufferRequestConfig_.height) || 534 !parcel.ReadInt32(bufferRequestConfig_.strideAlignment) || !parcel.ReadInt32(bufferRequestConfig_.format) || 535 !parcel.ReadUint64(bufferRequestConfig_.usage) || !parcel.ReadInt32(bufferRequestConfig_.timeout) || 536 !parcel.ReadUint32(colorGamut) || !parcel.ReadUint32(transform)) { 537 BLOGE("parcel read fail, seq: %{public}u.", sequenceNumber_); 538 return GSERROR_API_FAILED; 539 } 540 bufferRequestConfig_.colorGamut = static_cast<GraphicColorGamut>(colorGamut); 541 bufferRequestConfig_.transform = static_cast<GraphicTransformType>(transform); 542 return GSERROR_OK; 543} 544 545GSError SurfaceBufferImpl::ReadFromMessageParcel(MessageParcel& parcel) 546{ 547 auto handle = ReadBufferHandle(parcel); 548 SetBufferHandle(handle); 549 return handle ? GSERROR_OK : GSERROR_API_FAILED; 550} 551 552// return OH_NativeBuffer* is dangerous, need to refactor 553OH_NativeBuffer* SurfaceBufferImpl::SurfaceBufferToNativeBuffer() 554{ 555 return reinterpret_cast<OH_NativeBuffer *>(this); 556} 557 558uint32_t SurfaceBufferImpl::GetSeqNum() const 559{ 560 return sequenceNumber_; 561} 562 563GSError SurfaceBufferImpl::CheckBufferConfig(int32_t width, int32_t height, 564 int32_t format, uint64_t usage) 565{ 566 if (width <= 0 || height <= 0) { 567 BLOGE("width %{public}d height %{public}d", width, height); 568 return GSERROR_INVALID_ARGUMENTS; 569 } 570 571 if (format < 0 || format > GRAPHIC_PIXEL_FMT_BUTT) { 572 BLOGE("format is %{public}d", format); 573 return GSERROR_INVALID_ARGUMENTS; 574 } 575 576 return GSERROR_OK; 577} 578 579BufferWrapper SurfaceBufferImpl::GetBufferWrapper() 580{ 581 return {}; 582} 583 584void SurfaceBufferImpl::SetBufferWrapper(BufferWrapper wrapper) {} 585 586GSError SurfaceBufferImpl::SetMetadata(uint32_t key, const std::vector<uint8_t>& value) 587{ 588 if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) { 589 return GSERROR_INVALID_ARGUMENTS; 590 } 591 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer(); 592 if (displayBuffer == nullptr) { 593 return GSERROR_INTERNAL; 594 } 595 596 std::lock_guard<std::mutex> lock(mutex_); 597 if (handle_ == nullptr) { 598 return GSERROR_NOT_INIT; 599 } 600 601 if (MetaDataCachedLocked(key, value)) { 602 return GSERROR_OK; 603 } 604 605 auto dRet = displayBuffer->SetMetadata(*handle_, key, value); 606 if (dRet == GRAPHIC_DISPLAY_SUCCESS) { 607 // cache metaData 608 metaDataCache_[key] = value; 609 return GSERROR_OK; 610 } 611 BLOGE("SetMetadata Failed with %{public}d", dRet); 612 return GSERROR_HDI_ERROR; 613} 614 615GSError SurfaceBufferImpl::GetMetadata(uint32_t key, std::vector<uint8_t>& value) 616{ 617 if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) { 618 return GSERROR_INVALID_ARGUMENTS; 619 } 620 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer(); 621 if (displayBuffer == nullptr) { 622 return GSERROR_INTERNAL; 623 } 624 625 std::lock_guard<std::mutex> lock(mutex_); 626 if (handle_ == nullptr) { 627 return GSERROR_NOT_INIT; 628 } 629 auto dRet = displayBuffer->GetMetadata(*handle_, key, value); 630 if (dRet == GRAPHIC_DISPLAY_SUCCESS) { 631 return GSERROR_OK; 632 } 633 BLOGD("GetMetadata Failed with %{public}d", dRet); 634 return GSERROR_HDI_ERROR; 635} 636 637GSError SurfaceBufferImpl::ListMetadataKeys(std::vector<uint32_t>& keys) 638{ 639 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer(); 640 if (displayBuffer == nullptr) { 641 return GSERROR_INTERNAL; 642 } 643 keys.clear(); 644 std::lock_guard<std::mutex> lock(mutex_); 645 if (handle_ == nullptr) { 646 return GSERROR_NOT_INIT; 647 } 648 auto dRet = displayBuffer->ListMetadataKeys(*handle_, keys); 649 if (dRet == GRAPHIC_DISPLAY_SUCCESS) { 650 return GSERROR_OK; 651 } 652 BLOGE("ListMetadataKeys Failed with %{public}d", dRet); 653 return GSERROR_HDI_ERROR; 654} 655 656GSError SurfaceBufferImpl::EraseMetadataKey(uint32_t key) 657{ 658 if (key == 0 || key >= HDI::Display::Graphic::Common::V1_1::ATTRKEY_END) { 659 return GSERROR_INVALID_ARGUMENTS; 660 } 661 IDisplayBufferSptr displayBuffer = GetOrResetDisplayBuffer(); 662 if (displayBuffer == nullptr) { 663 return GSERROR_INTERNAL; 664 } 665 666 std::lock_guard<std::mutex> lock(mutex_); 667 if (handle_ == nullptr) { 668 return GSERROR_NOT_INIT; 669 } 670 auto dRet = displayBuffer->EraseMetadataKey(*handle_, key); 671 if (dRet == GRAPHIC_DISPLAY_SUCCESS) { 672 metaDataCache_.erase(key); 673 return GSERROR_OK; 674 } 675 BLOGE("EraseMetadataKey Failed with %{public}d", dRet); 676 return GSERROR_HDI_ERROR; 677} 678 679BufferRequestConfig SurfaceBufferImpl::GetBufferRequestConfig() const 680{ 681 std::lock_guard<std::mutex> lock(mutex_); 682 return bufferRequestConfig_; 683} 684 685void SurfaceBufferImpl::SetBufferRequestConfig(const BufferRequestConfig& config) 686{ 687 std::lock_guard<std::mutex> lock(mutex_); 688 bufferRequestConfig_ = config; 689} 690 691void SurfaceBufferImpl::SetConsumerAttachBufferFlag(bool value) 692{ 693 std::lock_guard<std::mutex> lock(mutex_); 694 isConsumerAttachBufferFlag_ = value; 695} 696 697bool SurfaceBufferImpl::GetConsumerAttachBufferFlag() 698{ 699 std::lock_guard<std::mutex> lock(mutex_); 700 return isConsumerAttachBufferFlag_; 701} 702} // namespace OHOS 703