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 #include "producer_surface.h"
17
18 #include <cinttypes>
19
20 #include "buffer_log.h"
21 #include "buffer_extra_data_impl.h"
22 #include "buffer_producer_listener.h"
23 #include "sync_fence.h"
24 #include "native_window.h"
25 #include "surface_utils.h"
26 #include "metadata_helper.h"
27
28 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
29 namespace OHOS {
30 constexpr int32_t FORCE_GLOBAL_ALPHA_MIN = -1;
31 constexpr int32_t FORCE_GLOBAL_ALPHA_MAX = 255;
CreateSurfaceAsProducer(sptr<IBufferProducer>& producer)32 sptr<Surface> Surface::CreateSurfaceAsProducer(sptr<IBufferProducer>& producer)
33 {
34 if (producer == nullptr) {
35 return nullptr;
36 }
37
38 sptr<ProducerSurface> surf = new ProducerSurface(producer);
39 GSError ret = surf->Init();
40 if (ret != GSERROR_OK) {
41 BLOGE("producer surf init failed");
42 return nullptr;
43 }
44 auto utils = SurfaceUtils::GetInstance();
45 utils->Add(surf->GetUniqueId(), surf);
46 return surf;
47 }
48
ProducerSurface(sptr<IBufferProducer>& producer)49 ProducerSurface::ProducerSurface(sptr<IBufferProducer>& producer)
50 {
51 producer_ = producer;
52 GetProducerInitInfo(initInfo_);
53 windowConfig_.width = initInfo_.width;
54 windowConfig_.height = initInfo_.height;
55 windowConfig_.usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_MEM_DMA;
56 windowConfig_.format = GRAPHIC_PIXEL_FMT_RGBA_8888;
57 windowConfig_.strideAlignment = 8; // default stride is 8
58 windowConfig_.timeout = 3000; // default timeout is 3000 ms
59 windowConfig_.colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
60 windowConfig_.transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
61 BLOGD("ProducerSurface ctor");
62 }
63
~ProducerSurface()64 ProducerSurface::~ProducerSurface()
65 {
66 BLOGD("~ProducerSurface dtor, name: %{public}s, uniqueId: %{public}" PRIu64 ".", name_.c_str(), queueId_);
67 Disconnect();
68 auto utils = SurfaceUtils::GetInstance();
69 utils->Remove(GetUniqueId());
70 }
71
GetProducerInitInfo(ProducerInitInfo& info)72 GSError ProducerSurface::GetProducerInitInfo(ProducerInitInfo& info)
73 {
74 if (producer_ == nullptr) {
75 return GSERROR_INVALID_ARGUMENTS;
76 }
77 return producer_->GetProducerInitInfo(info);
78 }
79
Init()80 GSError ProducerSurface::Init()
81 {
82 if (inited_.load()) {
83 return GSERROR_OK;
84 }
85 name_ = initInfo_.name;
86 queueId_ = initInfo_.uniqueId;
87 inited_.store(true);
88 BLOGD("Init name: %{public}s, uniqueId: %{public}" PRIu64 ".", name_.c_str(), queueId_);
89 return GSERROR_OK;
90 }
91
IsConsumer() const92 bool ProducerSurface::IsConsumer() const
93 {
94 return false;
95 }
96
GetProducer() const97 sptr<IBufferProducer> ProducerSurface::GetProducer() const
98 {
99 return producer_;
100 }
101
RequestBuffer(sptr<SurfaceBuffer>& buffer, sptr<SyncFence>& fence, BufferRequestConfig& config)102 GSError ProducerSurface::RequestBuffer(sptr<SurfaceBuffer>& buffer,
103 sptr<SyncFence>& fence, BufferRequestConfig& config)
104 {
105 if (producer_ == nullptr) {
106 return GSERROR_INVALID_ARGUMENTS;
107 }
108 IBufferProducer::RequestBufferReturnValue retval;
109 sptr<BufferExtraData> bedataimpl = new BufferExtraDataImpl;
110 GSError ret;
111 {
112 std::lock_guard<std::mutex> lockGuard(mutex_);
113 ret = producer_->RequestBuffer(config, bedataimpl, retval);
114 if (ret != GSERROR_OK) {
115 if (ret == GSERROR_NO_CONSUMER) {
116 CleanCacheLocked(false);
117 }
118 /**
119 * if server is connected, but result is failed.
120 * client needs to synchronize status.
121 */
122 if (retval.isConnected) {
123 isDisconnected_ = false;
124 }
125 BLOGD("RequestBuffer ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
126 return ret;
127 }
128 isDisconnected_ = false;
129 AddCacheLocked(bedataimpl, retval, config);
130 }
131 buffer = retval.buffer;
132 fence = retval.fence;
133
134 OutputRequestBufferLog(buffer);
135
136 ret = SetMetadataValve(buffer);
137 if (ret != GSERROR_OK) {
138 BLOGD("SetMetadataValve ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
139 }
140 return ret;
141 }
142
SetMetadataValve(sptr<SurfaceBuffer>& buffer)143 GSError ProducerSurface::SetMetadataValve(sptr<SurfaceBuffer>& buffer)
144 {
145 GSError ret = GSERROR_OK;
146 std::vector<uint8_t> metaData;
147 std::string value = GetUserData("ATTRKEY_COLORSPACE_INFO");
148 if (!value.empty()) {
149 ret = MetadataHelper::SetColorSpaceType(buffer, static_cast<CM_ColorSpaceType>(atoi(value.c_str())));
150 if (ret != GSERROR_OK) {
151 BLOGD("SetColorSpaceType ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
152 return ret;
153 }
154 }
155 value = GetUserData("OH_HDR_DYNAMIC_METADATA");
156 if (!value.empty()) {
157 metaData.resize(value.size());
158 metaData.assign(value.begin(), value.end());
159 ret = MetadataHelper::SetHDRStaticMetadata(buffer, metaData);
160 if (ret != GSERROR_OK) {
161 BLOGD("SetHDRStaticMetadata ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
162 return ret;
163 }
164 }
165 value = GetUserData("OH_HDR_STATIC_METADATA");
166 if (!value.empty()) {
167 metaData.resize(value.size());
168 metaData.assign(value.begin(), value.end());
169 ret = MetadataHelper::SetHDRStaticMetadata(buffer, metaData);
170 if (ret != GSERROR_OK) {
171 BLOGD("SetHDRStaticMetadata ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
172 return ret;
173 }
174 }
175 value = GetUserData("OH_HDR_METADATA_TYPE");
176 if (!value.empty()) {
177 ret = MetadataHelper::SetHDRMetadataType(buffer, static_cast<CM_HDR_Metadata_Type>(atoi(value.c_str())));
178 if (ret != GSERROR_OK) {
179 BLOGD("SetHDRMetadataType ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
180 }
181 }
182 return ret;
183 }
184
OutputRequestBufferLog(sptr<SurfaceBuffer>& buffer)185 void ProducerSurface::OutputRequestBufferLog(sptr<SurfaceBuffer>& buffer)
186 {
187 if (name_ != "RosenWeb") {
188 return;
189 }
190
191 static uint64_t fdRec[1024] = { 0 };
192 int32_t fd = buffer->GetBufferHandle()->fd;
193 int32_t fdTmp = fd < 1024 ? fd : fd % 1024;
194
195 if (fdRec[fdTmp] != queueId_) {
196 BLOGD("RequestBuffer, surfaceId %{public}" PRIu64 ", bufferFd: %{public}d.", queueId_, fd);
197 fdRec[fdTmp] = queueId_;
198 }
199 }
200
201 GSError ProducerSurface::AddCacheLocked(sptr<BufferExtraData>& bedataimpl,
202 IBufferProducer::RequestBufferReturnValue& retval, BufferRequestConfig& config)
203 {
204 // add cache
205 if (retval.buffer != nullptr) {
206 bufferProducerCache_[retval.sequence] = retval.buffer;
207 } else {
208 auto it = bufferProducerCache_.find(retval.sequence);
209 if (it == bufferProducerCache_.end()) {
210 BLOGE("cache not find buffer(%{public}u), uniqueId: %{public}" PRIu64 ".", retval.sequence, queueId_);
211 return SURFACE_ERROR_UNKOWN;
212 } else {
213 retval.buffer = it->second;
214 }
215 }
216 if (retval.buffer != nullptr) {
217 retval.buffer->SetSurfaceBufferColorGamut(config.colorGamut);
218 retval.buffer->SetSurfaceBufferTransform(config.transform);
219 retval.buffer->SetExtraData(bedataimpl);
220 }
221 for (auto it = retval.deletingBuffers.begin(); it != retval.deletingBuffers.end(); it++) {
222 uint32_t seqNum = static_cast<uint32_t>(*it);
223 bufferProducerCache_.erase(seqNum);
224 auto spNativeWindow = wpNativeWindow_.promote();
225 if (spNativeWindow != nullptr) {
226 auto& bufferCache = spNativeWindow->bufferCache_;
227 auto iter = bufferCache.find(seqNum);
228 if (iter != bufferCache.end()) {
229 NativeObjectUnreference(iter->second);
230 bufferCache.erase(iter);
231 }
232 }
233 }
234 return SURFACE_ERROR_OK;
235 }
236
237 GSError ProducerSurface::RequestBuffers(std::vector<sptr<SurfaceBuffer>>& buffers,
238 std::vector<sptr<SyncFence>>& fences, BufferRequestConfig& config)
239 {
240 if (producer_ == nullptr) {
241 return GSERROR_INVALID_ARGUMENTS;
242 }
243 std::vector<IBufferProducer::RequestBufferReturnValue> retvalues;
244 retvalues.resize(SURFACE_MAX_QUEUE_SIZE);
245 std::vector<sptr<BufferExtraData>> bedataimpls;
246 for (size_t i = 0; i < retvalues.size(); ++i) {
247 sptr<BufferExtraData> bedataimpl = new BufferExtraDataImpl;
248 bedataimpls.emplace_back(bedataimpl);
249 }
250 std::lock_guard<std::mutex> lockGuard(mutex_);
251 GSError ret = producer_->RequestBuffers(config, bedataimpls, retvalues);
252 if (ret != GSERROR_NO_BUFFER && ret != GSERROR_OK) {
253 /**
254 * if server is connected, but result is failed.
255 * client needs to synchronize status.
256 */
257 if (retvalues[0].isConnected) {
258 isDisconnected_ = false;
259 }
260 BLOGD("RequestBuffers ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
261 return ret;
262 }
263 isDisconnected_ = false;
264 for (size_t i = 0; i < retvalues.size(); ++i) {
265 AddCacheLocked(bedataimpls[i], retvalues[i], config);
266 buffers.emplace_back(retvalues[i].buffer);
267 fences.emplace_back(retvalues[i].fence);
268 }
269 return GSERROR_OK;
270 }
271
272 GSError ProducerSurface::FlushBuffer(sptr<SurfaceBuffer>& buffer,
273 const sptr<SyncFence>& fence, BufferFlushConfig& config)
274 {
275 BufferFlushConfigWithDamages configWithDamages;
276 configWithDamages.damages.push_back(config.damage);
277 configWithDamages.timestamp = config.timestamp;
278 configWithDamages.desiredPresentTimestamp = config.desiredPresentTimestamp;
279 return FlushBuffer(buffer, fence, configWithDamages);
280 }
281
282 GSError ProducerSurface::FlushBuffer(sptr<SurfaceBuffer>& buffer, const sptr<SyncFence>& fence,
283 BufferFlushConfigWithDamages& config)
284 {
285 if (buffer == nullptr || fence == nullptr || producer_ == nullptr) {
286 return GSERROR_INVALID_ARGUMENTS;
287 }
288
289 sptr<BufferExtraData> bedata = buffer->GetExtraData();
290 if (bedata == nullptr) {
291 return GSERROR_INVALID_ARGUMENTS;
292 }
293 auto ret = producer_->FlushBuffer(buffer->GetSeqNum(), bedata, fence, config);
294 if (ret == GSERROR_NO_CONSUMER) {
295 CleanCache();
296 BLOGD("FlushBuffer ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
297 }
298 return ret;
299 }
300
301 GSError ProducerSurface::FlushBuffers(const std::vector<sptr<SurfaceBuffer>>& buffers,
302 const std::vector<sptr<SyncFence>>& fences, const std::vector<BufferFlushConfigWithDamages>& configs)
303 {
304 if (buffers.size() == 0 || buffers.size() != fences.size() || producer_ == nullptr) {
305 return GSERROR_INVALID_ARGUMENTS;
306 }
307 for (size_t i = 0; i < buffers.size(); ++i) {
308 if (buffers[i] == nullptr || fences[i] == nullptr) {
309 BLOGE("buffer or fence is nullptr, i: %{public}zu, uniqueId: %{public}" PRIu64 ".", i, queueId_);
310 return GSERROR_INVALID_ARGUMENTS;
311 }
312 }
313 std::vector<sptr<BufferExtraData>> bedata;
314 bedata.reserve(buffers.size());
315 std::vector<uint32_t> sequences;
316 sequences.reserve(buffers.size());
317 for (uint32_t i = 0; i < buffers.size(); ++i) {
318 bedata.emplace_back(buffers[i]->GetExtraData());
319 sequences.emplace_back(buffers[i]->GetSeqNum());
320 }
321 auto ret = producer_->FlushBuffers(sequences, bedata, fences, configs);
322 if (ret == GSERROR_NO_CONSUMER) {
323 CleanCache();
324 BLOGD("FlushBuffers ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
325 }
326 return ret;
327 }
328
329 GSError ProducerSurface::GetLastFlushedBuffer(sptr<SurfaceBuffer>& buffer,
330 sptr<SyncFence>& fence, float matrix[16], bool isUseNewMatrix)
331 {
332 if (producer_ == nullptr) {
333 return GSERROR_INVALID_ARGUMENTS;
334 }
335 return producer_->GetLastFlushedBuffer(buffer, fence, matrix, isUseNewMatrix);
336 }
337
338 GSError ProducerSurface::RequestBuffer(sptr<SurfaceBuffer>& buffer,
339 int32_t& fence, BufferRequestConfig& config)
340 {
341 sptr<SyncFence> syncFence = SyncFence::InvalidFence();
342 auto ret = RequestBuffer(buffer, syncFence, config);
343 if (ret != GSERROR_OK) {
344 fence = -1;
345 return ret;
346 }
347 fence = syncFence->Dup();
348 return GSERROR_OK;
349 }
350
351 GSError ProducerSurface::CancelBuffer(sptr<SurfaceBuffer>& buffer)
352 {
353 if (buffer == nullptr || producer_ == nullptr) {
354 return SURFACE_ERROR_UNKOWN;
355 }
356
357 sptr<BufferExtraData> bedata = buffer->GetExtraData();
358 if (bedata == nullptr) {
359 return SURFACE_ERROR_UNKOWN;
360 }
361 return producer_->CancelBuffer(buffer->GetSeqNum(), bedata);
362 }
363
364 GSError ProducerSurface::FlushBuffer(sptr<SurfaceBuffer>& buffer,
365 int32_t fence, BufferFlushConfig& config)
366 {
367 sptr<SyncFence> syncFence = new SyncFence(fence);
368 return FlushBuffer(buffer, syncFence, config);
369 }
370
371 GSError ProducerSurface::AttachBufferToQueue(sptr<SurfaceBuffer> buffer)
372 {
373 if (buffer == nullptr || producer_ == nullptr) {
374 return SURFACE_ERROR_UNKOWN;
375 }
376 auto ret = producer_->AttachBufferToQueue(buffer);
377 if (ret == GSERROR_OK) {
378 std::lock_guard<std::mutex> lockGuard(mutex_);
379 if (bufferProducerCache_.find(buffer->GetSeqNum()) != bufferProducerCache_.end()) {
380 BLOGE("Attach buffer %{public}d, uniqueId: %{public}" PRIu64 ".", buffer->GetSeqNum(), queueId_);
381 return SURFACE_ERROR_BUFFER_IS_INCACHE;
382 }
383 bufferProducerCache_[buffer->GetSeqNum()] = buffer;
384 }
385 return ret;
386 }
387
388 GSError ProducerSurface::DetachBufferFromQueue(sptr<SurfaceBuffer> buffer)
389 {
390 if (buffer == nullptr || producer_ == nullptr) {
391 return SURFACE_ERROR_UNKOWN;
392 }
393 auto ret = producer_->DetachBufferFromQueue(buffer);
394 if (ret == GSERROR_OK) {
395 std::lock_guard<std::mutex> lockGuard(mutex_);
396 auto it = bufferProducerCache_.find(buffer->GetSeqNum());
397 if (it == bufferProducerCache_.end()) {
398 BLOGE("Detach buffer %{public}d, uniqueId: %{public}" PRIu64 ".", buffer->GetSeqNum(), queueId_);
399 return SURFACE_ERROR_BUFFER_NOT_INCACHE;
400 }
401 bufferProducerCache_.erase(it);
402 }
403 return ret;
404 }
405
406 GSError ProducerSurface::AttachBuffer(sptr<SurfaceBuffer>& buffer)
407 {
408 if (buffer == nullptr || producer_ == nullptr) {
409 return GSERROR_INVALID_ARGUMENTS;
410 }
411
412 return producer_->AttachBuffer(buffer);
413 }
414
415 GSError ProducerSurface::AttachBuffer(sptr<SurfaceBuffer>& buffer, int32_t timeOut)
416 {
417 if (buffer == nullptr || producer_ == nullptr) {
418 return GSERROR_INVALID_ARGUMENTS;
419 }
420
421 return producer_->AttachBuffer(buffer, timeOut);
422 }
423
424 GSError ProducerSurface::DetachBuffer(sptr<SurfaceBuffer>& buffer)
425 {
426 if (buffer == nullptr || producer_ == nullptr) {
427 return GSERROR_INVALID_ARGUMENTS;
428 }
429 return producer_->DetachBuffer(buffer);
430 }
431
432 GSError ProducerSurface::RegisterSurfaceDelegator(sptr<IRemoteObject> client)
433 {
434 if (client == nullptr) {
435 return GSERROR_INVALID_ARGUMENTS;
436 }
437 sptr<ProducerSurfaceDelegator> surfaceDelegator = ProducerSurfaceDelegator::Create();
438 if (surfaceDelegator == nullptr) {
439 BLOGE("surfaceDelegator is nullptr");
440 return GSERROR_INVALID_ARGUMENTS;
441 }
442 if (!surfaceDelegator->SetClient(client)) {
443 BLOGE("SetClient failed");
444 return GSERROR_INVALID_ARGUMENTS;
445 }
446
447 surfaceDelegator->SetSurface(this);
448 {
449 std::lock_guard<std::mutex> lockGuard(delegatorMutex_);
450 wpPSurfaceDelegator_ = surfaceDelegator;
451 }
452
453 auto releaseBufferCallBack = [weakThis = wptr(this)] (const sptr<SurfaceBuffer>& buffer,
454 const sptr<SyncFence>& fence) -> GSError {
455 auto pSurface = weakThis.promote();
456 if (pSurface == nullptr) {
457 BLOGE("pSurface is nullptr");
458 return GSERROR_INVALID_ARGUMENTS;
459 }
460 sptr<ProducerSurfaceDelegator> surfaceDelegator = nullptr;
461 {
462 std::lock_guard<std::mutex> lockGuard(pSurface->delegatorMutex_);
463 surfaceDelegator = pSurface->wpPSurfaceDelegator_.promote();
464 }
465 if (surfaceDelegator == nullptr) {
466 return GSERROR_INVALID_ARGUMENTS;
467 }
468 int error = surfaceDelegator->ReleaseBuffer(buffer, fence);
469 return static_cast<GSError>(error);
470 };
471 RegisterReleaseListener(releaseBufferCallBack);
472 return GSERROR_OK;
473 }
474
475 bool ProducerSurface::QueryIfBufferAvailable()
476 {
477 return false;
478 }
479
480 uint32_t ProducerSurface::GetQueueSize()
481 {
482 if (producer_ == nullptr) {
483 return 0;
484 }
485 return producer_->GetQueueSize();
486 }
487
488 GSError ProducerSurface::SetQueueSize(uint32_t queueSize)
489 {
490 if (producer_ == nullptr) {
491 return GSERROR_INVALID_ARGUMENTS;
492 }
493 return producer_->SetQueueSize(queueSize);
494 }
495
496 const std::string& ProducerSurface::GetName()
497 {
498 if (!inited_.load()) {
499 BLOGW("ProducerSurface is not initialized.");
500 }
501 return name_;
502 }
503
504 int32_t ProducerSurface::GetDefaultWidth()
505 {
506 if (producer_ == nullptr) {
507 return -1;
508 }
509 return producer_->GetDefaultWidth();
510 }
511
512 int32_t ProducerSurface::GetDefaultHeight()
513 {
514 if (producer_ == nullptr) {
515 return -1;
516 }
517 return producer_->GetDefaultHeight();
518 }
519
520 GraphicTransformType ProducerSurface::GetTransformHint() const
521 {
522 std::lock_guard<std::mutex> lockGuard(mutex_);
523 return lastSetTransformHint_;
524 }
525
526 GSError ProducerSurface::SetTransformHint(GraphicTransformType transformHint)
527 {
528 if (producer_ == nullptr) {
529 return GSERROR_INVALID_ARGUMENTS;
530 }
531 GSError err = producer_->SetTransformHint(transformHint);
532 if (err == GSERROR_OK) {
533 std::lock_guard<std::mutex> lockGuard(mutex_);
534 lastSetTransformHint_ = transformHint;
535 }
536 return err;
537 }
538
539 GSError ProducerSurface::SetDefaultUsage(uint64_t usage)
540 {
541 if (producer_ == nullptr) {
542 return GSERROR_INVALID_ARGUMENTS;
543 }
544 return producer_->SetDefaultUsage(usage);
545 }
546
547 uint64_t ProducerSurface::GetDefaultUsage()
548 {
549 if (producer_ == nullptr) {
550 return 0;
551 }
552 return producer_->GetDefaultUsage();
553 }
554
555 GSError ProducerSurface::SetSurfaceSourceType(OHSurfaceSource sourceType)
556 {
557 if (producer_ == nullptr) {
558 return GSERROR_INVALID_ARGUMENTS;
559 }
560 return producer_->SetSurfaceSourceType(sourceType);
561 }
562
563 OHSurfaceSource ProducerSurface::GetSurfaceSourceType() const
564 {
565 if (producer_ == nullptr) {
566 return OHSurfaceSource::OH_SURFACE_SOURCE_DEFAULT;
567 }
568 OHSurfaceSource sourceType = OHSurfaceSource::OH_SURFACE_SOURCE_DEFAULT;
569 if (producer_->GetSurfaceSourceType(sourceType) != GSERROR_OK) {
570 BLOGE("GetSurfaceSourceType failed, uniqueId: %{public}" PRIu64 ".", queueId_);
571 return OHSurfaceSource::OH_SURFACE_SOURCE_DEFAULT;
572 }
573 return sourceType;
574 }
575
576 GSError ProducerSurface::SetSurfaceAppFrameworkType(std::string appFrameworkType)
577 {
578 if (producer_ == nullptr) {
579 return GSERROR_INVALID_ARGUMENTS;
580 }
581 return producer_->SetSurfaceAppFrameworkType(appFrameworkType);
582 }
583
584 std::string ProducerSurface::GetSurfaceAppFrameworkType() const
585 {
586 if (producer_ == nullptr) {
587 return "";
588 }
589 std::string appFrameworkType = "";
590 if (producer_->GetSurfaceAppFrameworkType(appFrameworkType) != GSERROR_OK) {
591 BLOGE("GetSurfaceAppFrameworkType failed, uniqueId: %{public}" PRIu64 ".", queueId_);
592 return "";
593 }
594 return appFrameworkType;
595 }
596
597 GSError ProducerSurface::SetUserData(const std::string& key, const std::string& val)
598 {
599 std::lock_guard<std::mutex> lockGuard(lockMutex_);
600 if (userData_.size() >= SURFACE_MAX_USER_DATA_COUNT) {
601 BLOGE("userData_ size out: %{public}zu, uniqueId: %{public}" PRIu64 ".", userData_.size(), queueId_);
602 return GSERROR_OUT_OF_RANGE;
603 }
604
605 auto iterUserData = userData_.find(key);
606 if (iterUserData != userData_.end() && iterUserData->second == val) {
607 return GSERROR_API_FAILED;
608 }
609
610 userData_[key] = val;
611 auto iter = onUserDataChange_.begin();
612 while (iter != onUserDataChange_.end()) {
613 if (iter->second != nullptr) {
614 iter->second(key, val);
615 }
616 iter++;
617 }
618
619 return GSERROR_OK;
620 }
621
622 std::string ProducerSurface::GetUserData(const std::string& key)
623 {
624 std::lock_guard<std::mutex> lockGuard(lockMutex_);
625 if (userData_.find(key) != userData_.end()) {
626 return userData_[key];
627 }
628
629 return "";
630 }
631
632 GSError ProducerSurface::RegisterReleaseListener(OnReleaseFunc func)
633 {
634 if (func == nullptr || producer_ == nullptr) {
635 return GSERROR_INVALID_ARGUMENTS;
636 }
637 sptr<IProducerListener> listener;
638 {
639 std::lock_guard<std::mutex> lockGuard(listenerMutex_);
640 listener_ = new BufferReleaseProducerListener(func);
641 listener = listener_;
642 }
643 return producer_->RegisterReleaseListener(listener);
644 }
645
646 GSError ProducerSurface::RegisterReleaseListener(OnReleaseFuncWithFence funcWithFence)
647 {
648 if (funcWithFence == nullptr || producer_ == nullptr) {
649 return GSERROR_INVALID_ARGUMENTS;
650 }
651 sptr<IProducerListener> listener;
652 {
653 std::lock_guard<std::mutex> lockGuard(listenerMutex_);
654 listener_ = new BufferReleaseProducerListener(nullptr, funcWithFence);
655 listener = listener_;
656 }
657 return producer_->RegisterReleaseListener(listener);
658 }
659
660 GSError ProducerSurface::UnRegisterReleaseListener()
661 {
662 if (producer_ == nullptr) {
663 return GSERROR_INVALID_ARGUMENTS;
664 }
665 {
666 std::lock_guard<std::mutex> lockGuard(delegatorMutex_);
667 wpPSurfaceDelegator_ = nullptr;
668 }
669 {
670 std::lock_guard<std::mutex> lockGuard(listenerMutex_);
671 if (listener_ != nullptr) {
672 listener_->ResetReleaseFunc();
673 }
674 }
675 return producer_->UnRegisterReleaseListener();
676 }
677
678 GSError ProducerSurface::RegisterDeleteBufferListener(OnDeleteBufferFunc func, bool isForUniRedraw)
679 {
680 return GSERROR_NOT_SUPPORT;
681 }
682
683 GSError ProducerSurface::RegisterUserDataChangeListener(const std::string& funcName, OnUserDataChangeFunc func)
684 {
685 if (func == nullptr) {
686 return GSERROR_INVALID_ARGUMENTS;
687 }
688 std::lock_guard<std::mutex> lockGuard(lockMutex_);
689 if (onUserDataChange_.find(funcName) != onUserDataChange_.end()) {
690 BLOGD("already register func: %{public}s, uniqueId: %{public}" PRIu64 ".",
691 funcName.c_str(), queueId_);
692 return GSERROR_INVALID_ARGUMENTS;
693 }
694
695 onUserDataChange_[funcName] = func;
696 return GSERROR_OK;
697 }
698
699 GSError ProducerSurface::UnRegisterUserDataChangeListener(const std::string& funcName)
700 {
701 std::lock_guard<std::mutex> lockGuard(lockMutex_);
702 if (onUserDataChange_.erase(funcName) == 0) {
703 BLOGD("no register funcName: %{public}s, uniqueId: %{public}" PRIu64 ".", funcName.c_str(), queueId_);
704 return GSERROR_INVALID_ARGUMENTS;
705 }
706
707 return GSERROR_OK;
708 }
709
710 GSError ProducerSurface::ClearUserDataChangeListener()
711 {
712 std::lock_guard<std::mutex> lockGuard(lockMutex_);
713 onUserDataChange_.clear();
714 return GSERROR_OK;
715 }
716
717 bool ProducerSurface::IsRemote()
718 {
719 if (producer_ == nullptr || producer_->AsObject() == nullptr) {
720 return false;
721 }
722 return producer_->AsObject()->IsProxyObject();
723 }
724
725 void ProducerSurface::CleanAllLocked()
726 {
727 bufferProducerCache_.clear();
728 auto spNativeWindow = wpNativeWindow_.promote();
729 if (spNativeWindow != nullptr) {
730 auto& bufferCache = spNativeWindow->bufferCache_;
731 for (auto& [seqNum, buffer] : bufferCache) {
732 NativeObjectUnreference(buffer);
733 }
734 bufferCache.clear();
735 }
736 }
737
738 GSError ProducerSurface::CleanCacheLocked(bool cleanAll)
739 {
740 BLOGD("CleanCacheLocked, uniqueId: %{public}" PRIu64 ".", queueId_);
741 CleanAllLocked();
742 return producer_->CleanCache(cleanAll);
743 }
744
745 GSError ProducerSurface::CleanCache(bool cleanAll)
746 {
747 if (producer_ == nullptr) {
748 return GSERROR_INVALID_ARGUMENTS;
749 }
750 BLOGD("CleanCache, uniqueId: %{public}" PRIu64 ".", queueId_);
751 {
752 std::lock_guard<std::mutex> lockGuard(mutex_);
753 CleanAllLocked();
754 }
755 return producer_->CleanCache(cleanAll);
756 }
757
758 GSError ProducerSurface::GoBackground()
759 {
760 if (producer_ == nullptr) {
761 return GSERROR_INVALID_ARGUMENTS;
762 }
763 BLOGD("GoBackground, uniqueId: %{public}" PRIu64 ".", queueId_);
764 {
765 std::lock_guard<std::mutex> lockGuard(mutex_);
766 CleanAllLocked();
767 }
768 return producer_->GoBackground();
769 }
770
771 uint64_t ProducerSurface::GetUniqueId() const
772 {
773 if (!inited_.load()) {
774 BLOGW("ProducerSurface is not initialized.");
775 }
776 return queueId_;
777 }
778
779 GSError ProducerSurface::SetTransform(GraphicTransformType transform)
780 {
781 if (producer_ == nullptr) {
782 return GSERROR_INVALID_ARGUMENTS;
783 }
784 return producer_->SetTransform(transform);
785 }
786
787 GraphicTransformType ProducerSurface::GetTransform() const
788 {
789 if (producer_ == nullptr) {
790 return GraphicTransformType::GRAPHIC_ROTATE_BUTT;
791 }
792 GraphicTransformType transform = GraphicTransformType::GRAPHIC_ROTATE_BUTT;
793 if (producer_->GetTransform(transform) != GSERROR_OK) {
794 BLOGE("GetTransform failed, uniqueId: %{public}" PRIu64 ".", queueId_);
795 return GraphicTransformType::GRAPHIC_ROTATE_BUTT;
796 }
797 return transform;
798 }
799
800 GSError ProducerSurface::IsSupportedAlloc(const std::vector<BufferVerifyAllocInfo>& infos,
801 std::vector<bool>& supporteds)
802 {
803 if (producer_ == nullptr || infos.size() == 0 || infos.size() != supporteds.size()) {
804 return GSERROR_INVALID_ARGUMENTS;
805 }
806 return producer_->IsSupportedAlloc(infos, supporteds);
807 }
808
809 GSError ProducerSurface::Connect()
810 {
811 if (producer_ == nullptr) {
812 return GSERROR_INVALID_ARGUMENTS;
813 }
814 std::lock_guard<std::mutex> lockGuard(mutex_);
815 if (!isDisconnected_) {
816 BLOGE("Surface has been connect, uniqueId: %{public}" PRIu64 ".", queueId_);
817 return SURFACE_ERROR_CONSUMER_IS_CONNECTED;
818 }
819 BLOGD("Connect, uniqueId: %{public}" PRIu64 ".", queueId_);
820 GSError ret = producer_->Connect();
821 if (ret == GSERROR_OK) {
822 isDisconnected_ = false;
823 }
824 return ret;
825 }
826
827 GSError ProducerSurface::Disconnect()
828 {
829 if (producer_ == nullptr) {
830 return GSERROR_INVALID_ARGUMENTS;
831 }
832 std::lock_guard<std::mutex> lockGuard(mutex_);
833 if (isDisconnected_) {
834 BLOGD("Surface is disconnect, uniqueId: %{public}" PRIu64 ".", queueId_);
835 return SURFACE_ERROR_CONSUMER_DISCONNECTED;
836 }
837 BLOGD("Disconnect, uniqueId: %{public}" PRIu64 ".", queueId_);
838 CleanAllLocked();
839 GSError ret = producer_->Disconnect();
840 if (ret == GSERROR_OK) {
841 isDisconnected_ = true;
842 }
843 return ret;
844 }
845
846 GSError ProducerSurface::SetScalingMode(uint32_t sequence, ScalingMode scalingMode)
847 {
848 if (producer_ == nullptr || scalingMode < ScalingMode::SCALING_MODE_FREEZE ||
849 scalingMode > ScalingMode::SCALING_MODE_SCALE_FIT) {
850 return GSERROR_INVALID_ARGUMENTS;
851 }
852 return producer_->SetScalingMode(sequence, scalingMode);
853 }
854
855 GSError ProducerSurface::SetScalingMode(ScalingMode scalingMode)
856 {
857 if (producer_ == nullptr || scalingMode < ScalingMode::SCALING_MODE_FREEZE ||
858 scalingMode > ScalingMode::SCALING_MODE_SCALE_FIT) {
859 return GSERROR_INVALID_ARGUMENTS;
860 }
861 return producer_->SetScalingMode(scalingMode);
862 }
863
864 void ProducerSurface::SetBufferHold(bool hold)
865 {
866 if (producer_ == nullptr) {
867 return;
868 }
869 producer_->SetBufferHold(hold);
870 }
871
872 GSError ProducerSurface::SetMetaData(uint32_t sequence, const std::vector<GraphicHDRMetaData>& metaData)
873 {
874 if (producer_ == nullptr || metaData.size() == 0) {
875 return GSERROR_INVALID_ARGUMENTS;
876 }
877 return producer_->SetMetaData(sequence, metaData);
878 }
879
880 GSError ProducerSurface::SetMetaDataSet(uint32_t sequence, GraphicHDRMetadataKey key,
881 const std::vector<uint8_t>& metaData)
882 {
883 if (producer_ == nullptr || key < GraphicHDRMetadataKey::GRAPHIC_MATAKEY_RED_PRIMARY_X ||
884 key > GraphicHDRMetadataKey::GRAPHIC_MATAKEY_HDR_VIVID || metaData.size() == 0) {
885 return GSERROR_INVALID_ARGUMENTS;
886 }
887 return producer_->SetMetaDataSet(sequence, key, metaData);
888 }
889
890 GSError ProducerSurface::SetTunnelHandle(const GraphicExtDataHandle *handle)
891 {
892 if (producer_ == nullptr) {
893 return GSERROR_INVALID_ARGUMENTS;
894 }
895 return producer_->SetTunnelHandle(handle);
896 }
897
898 GSError ProducerSurface::GetPresentTimestamp(uint32_t sequence, GraphicPresentTimestampType type,
899 int64_t& time) const
900 {
901 if (producer_ == nullptr || type <= GraphicPresentTimestampType::GRAPHIC_DISPLAY_PTS_UNSUPPORTED ||
902 type > GraphicPresentTimestampType::GRAPHIC_DISPLAY_PTS_TIMESTAMP) {
903 return GSERROR_INVALID_ARGUMENTS;
904 }
905 return producer_->GetPresentTimestamp(sequence, type, time);
906 }
907
908 GSError ProducerSurface::SetWptrNativeWindowToPSurface(void* nativeWindow)
909 {
910 if (nativeWindow == nullptr) {
911 return GSERROR_INVALID_ARGUMENTS;
912 }
913 NativeWindow *nw = reinterpret_cast<NativeWindow *>(nativeWindow);
914 std::lock_guard<std::mutex> lockGuard(mutex_);
915 wpNativeWindow_ = nw;
916 return GSERROR_OK;
917 }
918
919 void ProducerSurface::SetRequestWidthAndHeight(int32_t width, int32_t height)
920 {
921 std::lock_guard<std::mutex> lockGuard(mutex_);
922 requestWidth_ = width;
923 requestHeight_ = height;
924 }
925
926 int32_t ProducerSurface::GetRequestWidth()
927 {
928 std::lock_guard<std::mutex> lockGuard(mutex_);
929 return requestWidth_;
930 }
931
932 int32_t ProducerSurface::GetRequestHeight()
933 {
934 std::lock_guard<std::mutex> lockGuard(mutex_);
935 return requestHeight_;
936 }
937
938 void ProducerSurface::SetWindowConfig(const BufferRequestConfig& config)
939 {
940 std::lock_guard<std::mutex> lockGuard(mutex_);
941 windowConfig_ = config;
942 }
943
944 void ProducerSurface::SetWindowConfigWidthAndHeight(int32_t width, int32_t height)
945 {
946 std::lock_guard<std::mutex> lockGuard(mutex_);
947 windowConfig_.width = width;
948 windowConfig_.height = height;
949 }
950
951 void ProducerSurface::SetWindowConfigStride(int32_t stride)
952 {
953 std::lock_guard<std::mutex> lockGuard(mutex_);
954 windowConfig_.strideAlignment = stride;
955 }
956
957 void ProducerSurface::SetWindowConfigFormat(int32_t format)
958 {
959 std::lock_guard<std::mutex> lockGuard(mutex_);
960 windowConfig_.format = format;
961 }
962
963 void ProducerSurface::SetWindowConfigUsage(uint64_t usage)
964 {
965 std::lock_guard<std::mutex> lockGuard(mutex_);
966 windowConfig_.usage = usage;
967 }
968
969 void ProducerSurface::SetWindowConfigTimeout(int32_t timeout)
970 {
971 std::lock_guard<std::mutex> lockGuard(mutex_);
972 windowConfig_.timeout = timeout;
973 }
974
975 void ProducerSurface::SetWindowConfigColorGamut(GraphicColorGamut colorGamut)
976 {
977 std::lock_guard<std::mutex> lockGuard(mutex_);
978 windowConfig_.colorGamut = colorGamut;
979 }
980
981 void ProducerSurface::SetWindowConfigTransform(GraphicTransformType transform)
982 {
983 std::lock_guard<std::mutex> lockGuard(mutex_);
984 windowConfig_.transform = transform;
985 }
986
987 BufferRequestConfig ProducerSurface::GetWindowConfig()
988 {
989 std::lock_guard<std::mutex> lockGuard(mutex_);
990 return windowConfig_;
991 }
992
993 GSError ProducerSurface::SetHdrWhitePointBrightness(float brightness)
994 {
995 if (producer_ == nullptr) {
996 return GSERROR_INVALID_ARGUMENTS;
997 }
998 if (brightness < 0.0 || brightness > 1.0) {
999 BLOGE("brightness:%{public}f, uniqueId: %{public}" PRIu64 ".", brightness, queueId_);
1000 return GSERROR_INVALID_ARGUMENTS;
1001 }
1002 return producer_->SetHdrWhitePointBrightness(brightness);
1003 }
1004
1005 GSError ProducerSurface::SetSdrWhitePointBrightness(float brightness)
1006 {
1007 if (producer_ == nullptr) {
1008 return GSERROR_INVALID_ARGUMENTS;
1009 }
1010 if (brightness < 0.0 || brightness > 1.0) {
1011 BLOGE("brightness:%{public}f, uniqueId: %{public}" PRIu64 ".", brightness, queueId_);
1012 return GSERROR_INVALID_ARGUMENTS;
1013 }
1014 return producer_->SetSdrWhitePointBrightness(brightness);
1015 }
1016
1017 GSError ProducerSurface::AcquireLastFlushedBuffer(sptr<SurfaceBuffer>& buffer, sptr<SyncFence>& fence,
1018 float matrix[16], uint32_t matrixSize, bool isUseNewMatrix)
1019 {
1020 if (producer_ == nullptr) {
1021 return GSERROR_INVALID_ARGUMENTS;
1022 }
1023 return producer_->AcquireLastFlushedBuffer(buffer, fence, matrix, matrixSize, isUseNewMatrix);
1024 }
1025
1026 GSError ProducerSurface::ReleaseLastFlushedBuffer(sptr<SurfaceBuffer> buffer)
1027 {
1028 if (buffer == nullptr || producer_ == nullptr) {
1029 return GSERROR_INVALID_ARGUMENTS;
1030 }
1031 return producer_->ReleaseLastFlushedBuffer(buffer->GetSeqNum());
1032 }
1033
1034 GSError ProducerSurface::SetGlobalAlpha(int32_t alpha)
1035 {
1036 if (producer_ == nullptr || alpha < FORCE_GLOBAL_ALPHA_MIN || alpha > FORCE_GLOBAL_ALPHA_MAX) {
1037 BLOGE("Invalid producer global alpha value: %{public}d, queueId: %{public}" PRIu64 ".", alpha, queueId_);
1038 return GSERROR_INVALID_ARGUMENTS;
1039 }
1040 return producer_->SetGlobalAlpha(alpha);
1041 }
1042 } // namespace OHOS
1043