• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 #include <sys/ioctl.h>
20 
21 #include <linux/dma-buf.h>
22 
23 #include "buffer_log.h"
24 #include "buffer_extra_data_impl.h"
25 #include "buffer_producer_listener.h"
26 #include "sync_fence.h"
27 #include "native_window.h"
28 #include "surface_utils.h"
29 #include "surface_trace.h"
30 #include "metadata_helper.h"
31 #include "sync_fence_tracker.h"
32 #include "acquire_fence_manager.h"
33 
34 #define DMA_BUF_SET_TYPE _IOW(DMA_BUF_BASE, 2, const char *)
35 
36 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
37 namespace OHOS {
38 constexpr int32_t FORCE_GLOBAL_ALPHA_MIN = -1;
39 constexpr int32_t FORCE_GLOBAL_ALPHA_MAX = 255;
40 constexpr int32_t DAMAGES_MAX_SIZE = 1000;
CreateSurfaceAsProducer(sptr<IBufferProducer> & producer)41 sptr<Surface> Surface::CreateSurfaceAsProducer(sptr<IBufferProducer>& producer)
42 {
43     if (producer == nullptr) {
44         return nullptr;
45     }
46 
47     sptr<ProducerSurface> surf = new ProducerSurface(producer);
48     GSError ret = surf->Init();
49     if (ret != GSERROR_OK) {
50         BLOGE("producer surf init failed");
51         return nullptr;
52     }
53     auto utils = SurfaceUtils::GetInstance();
54     utils->Add(surf->GetUniqueId(), surf);
55     return surf;
56 }
57 
ProducerSurface(sptr<IBufferProducer> & producer)58 ProducerSurface::ProducerSurface(sptr<IBufferProducer>& producer)
59 {
60     initInfo_.propertyListener = new PropertyChangeProducerListener([this](SurfaceProperty property) {
61         return PropertyChangeCallback(property);
62     });
63     producer_ = producer;
64     GetProducerInitInfo(initInfo_);
65     lastSetTransformHint_ = static_cast<GraphicTransformType>(initInfo_.transformHint);
66     windowConfig_.width = initInfo_.width;
67     windowConfig_.height = initInfo_.height;
68     windowConfig_.usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_MEM_DMA;
69     windowConfig_.format = GRAPHIC_PIXEL_FMT_RGBA_8888;
70     windowConfig_.strideAlignment = 8;     // default stride is 8
71     windowConfig_.timeout = 3000;          // default timeout is 3000 ms
72     windowConfig_.colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
73     windowConfig_.transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
74     BLOGD("ProducerSurface ctor, name: %{public}s, uniqueId: %{public}" PRIu64 ", appName: %{public}s, isInHebcList:"
75         " %{public}d.", initInfo_.name.c_str(), initInfo_.uniqueId, initInfo_.appName.c_str(), initInfo_.isInHebcList);
76 }
77 
~ProducerSurface()78 ProducerSurface::~ProducerSurface()
79 {
80     BLOGD("~ProducerSurface dtor, name: %{public}s, uniqueId: %{public}" PRIu64 ".", name_.c_str(), queueId_);
81     ResetPropertyListenerInner(initInfo_.producerId);
82     Disconnect();
83     auto utils = SurfaceUtils::GetInstance();
84     utils->Remove(GetUniqueId());
85 }
86 
GetProducerInitInfo(ProducerInitInfo & info)87 GSError ProducerSurface::GetProducerInitInfo(ProducerInitInfo& info)
88 {
89     if (producer_ == nullptr) {
90         return GSERROR_INVALID_ARGUMENTS;
91     }
92     return producer_->GetProducerInitInfo(info);
93 }
94 
Init()95 GSError ProducerSurface::Init()
96 {
97     if (inited_.load()) {
98         return GSERROR_OK;
99     }
100     name_ = initInfo_.name;
101     queueId_ = initInfo_.uniqueId;
102     bufferName_ = initInfo_.bufferName;
103     inited_.store(true);
104     return GSERROR_OK;
105 }
106 
IsConsumer() const107 bool ProducerSurface::IsConsumer() const
108 {
109     return false;
110 }
111 
GetProducer() const112 sptr<IBufferProducer> ProducerSurface::GetProducer() const
113 {
114     return producer_;
115 }
116 
RequestBufferLocked(sptr<SurfaceBuffer> & buffer,sptr<SyncFence> & fence,BufferRequestConfig & config)117 GSError ProducerSurface::RequestBufferLocked(sptr<SurfaceBuffer>& buffer,
118     sptr<SyncFence>& fence, BufferRequestConfig& config)
119 {
120     if (producer_ == nullptr) {
121         return GSERROR_INVALID_ARGUMENTS;
122     }
123     IBufferProducer::RequestBufferReturnValue retval;
124     sptr<BufferExtraData> bedataimpl = new BufferExtraDataImpl;
125 
126     GSError ret = producer_->RequestBuffer(config, bedataimpl, retval);
127 #ifdef HIPERF_TRACE_ENABLE
128     BLOGW("hiperf_surface RequestBuffer %{public}lx %{public}u %{public}u %{public}u",
129         config.usage, config.format, config.width, config.height);
130 #endif
131     if (ret != GSERROR_OK) {
132         if (ret == GSERROR_NO_CONSUMER) {
133             CleanCacheLocked(false);
134         }
135         /**
136          * if server is connected, but result is failed.
137          * client needs to synchronize status.
138          */
139         if (retval.isConnected) {
140             isDisconnected_ = false;
141         }
142         BLOGD("RequestBuffer ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
143         return ret;
144     }
145     isDisconnected_ = false;
146     AddCacheLocked(bedataimpl, retval, config);
147     buffer = retval.buffer;
148     fence = retval.fence;
149 
150     if (SetMetadataValue(buffer) != GSERROR_OK) {
151         BLOGD("SetMetadataValue fail, uniqueId: %{public}" PRIu64 ".", queueId_);
152     }
153 
154     if (IsTagEnabled(HITRACE_TAG_GRAPHIC_AGP)) {
155         static SyncFenceTracker releaseFenceThread("Release Fence");
156         releaseFenceThread.TrackFence(fence);
157     }
158     return ret;
159 }
160 
RequestBuffer(sptr<SurfaceBuffer> & buffer,sptr<SyncFence> & fence,BufferRequestConfig & config)161 GSError ProducerSurface::RequestBuffer(sptr<SurfaceBuffer>& buffer,
162                                        sptr<SyncFence>& fence, BufferRequestConfig& config)
163 {
164     std::lock_guard<std::mutex> lockGuard(mutex_);
165     return RequestBufferLocked(buffer, fence, config);
166 }
167 
SetMetadataValue(sptr<SurfaceBuffer> & buffer)168 GSError ProducerSurface::SetMetadataValue(sptr<SurfaceBuffer>& buffer)
169 {
170     GSError ret = GSERROR_OK;
171     std::vector<uint8_t> metaData;
172     std::string value = GetUserData("ATTRKEY_COLORSPACE_INFO");
173     if (!value.empty()) {
174         ret = MetadataHelper::SetColorSpaceType(buffer, static_cast<CM_ColorSpaceType>(atoi(value.c_str())));
175         if (ret != GSERROR_OK) {
176             return ret;
177         }
178     }
179     value = GetUserData("OH_HDR_DYNAMIC_METADATA");
180     if (!value.empty()) {
181         metaData.resize(value.size());
182         metaData.assign(value.begin(), value.end());
183         ret = MetadataHelper::SetHDRDynamicMetadata(buffer, metaData);
184         if (ret != GSERROR_OK) {
185             return ret;
186         }
187     }
188     value = GetUserData("OH_HDR_STATIC_METADATA");
189     if (!value.empty()) {
190         metaData.resize(value.size());
191         metaData.assign(value.begin(), value.end());
192         ret = MetadataHelper::SetHDRStaticMetadata(buffer, metaData);
193         if (ret != GSERROR_OK) {
194             return ret;
195         }
196     }
197     value = GetUserData("OH_HDR_METADATA_TYPE");
198     if (!value.empty()) {
199         ret = MetadataHelper::SetHDRMetadataType(buffer, static_cast<CM_HDR_Metadata_Type>(atoi(value.c_str())));
200     }
201     return ret;
202 }
203 
SetBufferConfigLocked(sptr<BufferExtraData> & bedataimpl,IBufferProducer::RequestBufferReturnValue & retval,BufferRequestConfig & config)204 void ProducerSurface::SetBufferConfigLocked(sptr<BufferExtraData>& bedataimpl,
205     IBufferProducer::RequestBufferReturnValue& retval, BufferRequestConfig& config)
206 {
207     if (retval.buffer != nullptr) {
208         retval.buffer->SetSurfaceBufferColorGamut(config.colorGamut);
209         retval.buffer->SetSurfaceBufferTransform(config.transform);
210         retval.buffer->SetExtraData(bedataimpl);
211     }
212 }
213 
DeleteCacheBufferLocked(sptr<BufferExtraData> & bedataimpl,IBufferProducer::RequestBufferReturnValue & retval,BufferRequestConfig & config)214 void ProducerSurface::DeleteCacheBufferLocked(sptr<BufferExtraData>& bedataimpl,
215     IBufferProducer::RequestBufferReturnValue& retval, BufferRequestConfig& config)
216 {
217     for (auto it = retval.deletingBuffers.begin(); it != retval.deletingBuffers.end(); it++) {
218         uint32_t seqNum = static_cast<uint32_t>(*it);
219         bufferProducerCache_.erase(seqNum);
220         auto spNativeWindow = wpNativeWindow_.promote();
221         if (spNativeWindow != nullptr) {
222             std::lock_guard<std::mutex> lockGuard(spNativeWindow->mutex_);
223             auto& bufferCache = spNativeWindow->bufferCache_;
224             auto iter = bufferCache.find(seqNum);
225             if (iter != bufferCache.end()) {
226                 NativeObjectUnreference(iter->second);
227                 bufferCache.erase(iter);
228             }
229         }
230     }
231 }
232 
AddCacheLocked(sptr<BufferExtraData> & bedataimpl,IBufferProducer::RequestBufferReturnValue & retval,BufferRequestConfig & config)233 GSError ProducerSurface::AddCacheLocked(sptr<BufferExtraData>& bedataimpl,
234     IBufferProducer::RequestBufferReturnValue& retval, BufferRequestConfig& config)
235 {
236     // add cache
237     if (retval.buffer != nullptr) {
238         bufferProducerCache_[retval.sequence] = retval.buffer;
239         ReleasePreCacheBuffer(static_cast<int>(bufferProducerCache_.size()));
240         if (bufferName_ != "") {
241             int fd = retval.buffer->GetFileDescriptor();
242             if (fd > 0) {
243                 ioctl(fd, DMA_BUF_SET_TYPE, bufferName_.c_str());
244             }
245         } else if (config.sourceType == GRAPHIC_SDK_TYPE) {
246             int fd = retval.buffer->GetFileDescriptor();
247             if (fd > 0) {
248                 ioctl(fd, DMA_BUF_SET_TYPE, "external");
249             }
250         }
251     } else {
252         auto it = bufferProducerCache_.find(retval.sequence);
253         if (it == bufferProducerCache_.end()) {
254             DeleteCacheBufferLocked(bedataimpl, retval, config);
255             BLOGE("cache not find buffer(%{public}u), uniqueId: %{public}" PRIu64 ".", retval.sequence, queueId_);
256             return SURFACE_ERROR_UNKOWN;
257         } else {
258             retval.buffer = it->second;
259         }
260     }
261     SetBufferConfigLocked(bedataimpl, retval, config);
262     DeleteCacheBufferLocked(bedataimpl, retval, config);
263     return SURFACE_ERROR_OK;
264 }
265 
RequestBuffers(std::vector<sptr<SurfaceBuffer>> & buffers,std::vector<sptr<SyncFence>> & fences,BufferRequestConfig & config)266 GSError ProducerSurface::RequestBuffers(std::vector<sptr<SurfaceBuffer>>& buffers,
267     std::vector<sptr<SyncFence>>& fences, BufferRequestConfig& config)
268 {
269     if (producer_ == nullptr) {
270         return GSERROR_INVALID_ARGUMENTS;
271     }
272     std::vector<IBufferProducer::RequestBufferReturnValue> retvalues;
273     retvalues.resize(SURFACE_MAX_QUEUE_SIZE);
274     std::vector<sptr<BufferExtraData>> bedataimpls;
275     for (size_t i = 0; i < retvalues.size(); ++i) {
276         sptr<BufferExtraData> bedataimpl = new BufferExtraDataImpl;
277         bedataimpls.emplace_back(bedataimpl);
278     }
279     std::lock_guard<std::mutex> lockGuard(mutex_);
280     GSError ret = producer_->RequestBuffers(config, bedataimpls, retvalues);
281     if (ret != GSERROR_NO_BUFFER && ret != GSERROR_OK) {
282         /**
283          * if server is connected, but result is failed.
284          * client needs to synchronize status.
285          */
286         if (retvalues[0].isConnected) {
287             isDisconnected_ = false;
288         }
289         BLOGD("RequestBuffers ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
290         return ret;
291     }
292     isDisconnected_ = false;
293     for (size_t i = 0; i < retvalues.size(); ++i) {
294         AddCacheLocked(bedataimpls[i], retvalues[i], config);
295         buffers.emplace_back(retvalues[i].buffer);
296         fences.emplace_back(retvalues[i].fence);
297     }
298     return GSERROR_OK;
299 }
300 
FlushBuffer(sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & fence,BufferFlushConfig & config)301 GSError ProducerSurface::FlushBuffer(sptr<SurfaceBuffer>& buffer,
302                                      const sptr<SyncFence>& fence, BufferFlushConfig& config)
303 {
304     BufferFlushConfigWithDamages configWithDamages;
305     configWithDamages.damages.push_back(config.damage);
306     configWithDamages.timestamp = config.timestamp;
307     configWithDamages.desiredPresentTimestamp = config.desiredPresentTimestamp;
308     return FlushBuffer(buffer, fence, configWithDamages);
309 }
310 
FlushBuffer(sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & fence,BufferFlushConfigWithDamages & config,bool needLock)311 GSError ProducerSurface::FlushBuffer(sptr<SurfaceBuffer>& buffer, const sptr<SyncFence>& fence,
312                                      BufferFlushConfigWithDamages& config, bool needLock)
313 {
314     if (buffer == nullptr || fence == nullptr || producer_ == nullptr) {
315         return GSERROR_INVALID_ARGUMENTS;
316     }
317 
318     sptr<BufferExtraData> bedata = buffer->GetExtraData();
319     if (bedata == nullptr) {
320         return GSERROR_INVALID_ARGUMENTS;
321     }
322     auto ret = producer_->FlushBuffer(buffer->GetSeqNum(), bedata, fence, config);
323     bool traceTag = IsTagEnabled(HITRACE_TAG_GRAPHIC_AGP);
324     AcquireFenceTracker::TrackFence(fence, traceTag);
325     if (ret == GSERROR_NO_CONSUMER) {
326         if (needLock == true) {
327             CleanCache();
328         } else {
329             CleanCacheLocked(false);
330         }
331         BLOGD("FlushBuffer ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
332     }
333     return ret;
334 }
335 
FlushBuffers(const std::vector<sptr<SurfaceBuffer>> & buffers,const std::vector<sptr<SyncFence>> & fences,const std::vector<BufferFlushConfigWithDamages> & configs)336 GSError ProducerSurface::FlushBuffers(const std::vector<sptr<SurfaceBuffer>>& buffers,
337     const std::vector<sptr<SyncFence>>& fences, const std::vector<BufferFlushConfigWithDamages>& configs)
338 {
339     if (buffers.size() == 0 || buffers.size() != fences.size() || producer_ == nullptr
340         || buffers.size() > SURFACE_MAX_QUEUE_SIZE) {
341         return GSERROR_INVALID_ARGUMENTS;
342     }
343     for (size_t i = 0; i < buffers.size(); ++i) {
344         if (buffers[i] == nullptr || fences[i] == nullptr) {
345             BLOGE("buffer or fence is nullptr, i: %{public}zu, uniqueId: %{public}" PRIu64 ".", i, queueId_);
346             return GSERROR_INVALID_ARGUMENTS;
347         }
348     }
349     std::vector<sptr<BufferExtraData>> bedata;
350     bedata.reserve(buffers.size());
351     std::vector<uint32_t> sequences;
352     sequences.reserve(buffers.size());
353     for (uint32_t i = 0; i < buffers.size(); ++i) {
354         bedata.emplace_back(buffers[i]->GetExtraData());
355         sequences.emplace_back(buffers[i]->GetSeqNum());
356     }
357     auto ret = producer_->FlushBuffers(sequences, bedata, fences, configs);
358     if (ret == GSERROR_NO_CONSUMER) {
359         CleanCache();
360         BLOGD("FlushBuffers ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
361     }
362     return ret;
363 }
364 
GetLastFlushedBuffer(sptr<SurfaceBuffer> & buffer,sptr<SyncFence> & fence,float matrix[16],bool isUseNewMatrix)365 GSError ProducerSurface::GetLastFlushedBuffer(sptr<SurfaceBuffer>& buffer,
366     sptr<SyncFence>& fence, float matrix[16], bool isUseNewMatrix)
367 {
368     if (producer_ == nullptr) {
369         return GSERROR_INVALID_ARGUMENTS;
370     }
371     return producer_->GetLastFlushedBuffer(buffer, fence, matrix, isUseNewMatrix);
372 }
373 
RequestBuffer(sptr<SurfaceBuffer> & buffer,int32_t & fence,BufferRequestConfig & config)374 GSError ProducerSurface::RequestBuffer(sptr<SurfaceBuffer>& buffer,
375     int32_t& fence, BufferRequestConfig& config)
376 {
377     sptr<SyncFence> syncFence = SyncFence::InvalidFence();
378     auto ret = RequestBuffer(buffer, syncFence, config);
379     if (ret != GSERROR_OK) {
380         fence = -1;
381         return ret;
382     }
383     fence = syncFence->Dup();
384     return GSERROR_OK;
385 }
386 
CancelBuffer(sptr<SurfaceBuffer> & buffer)387 GSError ProducerSurface::CancelBuffer(sptr<SurfaceBuffer>& buffer)
388 {
389     if (buffer == nullptr || producer_ == nullptr) {
390         return SURFACE_ERROR_UNKOWN;
391     }
392 
393     sptr<BufferExtraData> bedata = buffer->GetExtraData();
394     if (bedata == nullptr) {
395         return SURFACE_ERROR_UNKOWN;
396     }
397     auto ret = producer_->CancelBuffer(buffer->GetSeqNum(), bedata);
398     if (ret == GSERROR_OK) {
399         std::lock_guard<std::mutex> lockGuard(mutex_);
400         mLockedBuffer_ = nullptr;
401         region_.rectNumber = 0;
402         delete[] region_.rects;
403         region_.rects = nullptr;
404     }
405     return ret;
406 }
407 
FlushBuffer(sptr<SurfaceBuffer> & buffer,int32_t fence,BufferFlushConfig & config)408 GSError ProducerSurface::FlushBuffer(sptr<SurfaceBuffer>& buffer,
409     int32_t fence, BufferFlushConfig& config)
410 {
411     sptr<SyncFence> syncFence = new SyncFence(fence);
412     return FlushBuffer(buffer, syncFence, config);
413 }
414 
AttachBufferToQueue(sptr<SurfaceBuffer> buffer)415 GSError ProducerSurface::AttachBufferToQueue(sptr<SurfaceBuffer> buffer)
416 {
417     if (buffer == nullptr || producer_ == nullptr) {
418         return SURFACE_ERROR_UNKOWN;
419     }
420     auto ret = producer_->AttachBufferToQueue(buffer);
421     if (ret == GSERROR_OK) {
422         std::lock_guard<std::mutex> lockGuard(mutex_);
423         if (bufferProducerCache_.find(buffer->GetSeqNum()) != bufferProducerCache_.end()) {
424             BLOGE("Attach buffer %{public}d, uniqueId: %{public}" PRIu64 ".", buffer->GetSeqNum(), queueId_);
425             return SURFACE_ERROR_BUFFER_IS_INCACHE;
426         }
427         bufferProducerCache_[buffer->GetSeqNum()] = buffer;
428         ReleasePreCacheBuffer(static_cast<int>(bufferProducerCache_.size()));
429     }
430     return ret;
431 }
432 
DetachBufferFromQueue(sptr<SurfaceBuffer> buffer,bool isReserveSlot)433 GSError ProducerSurface::DetachBufferFromQueue(sptr<SurfaceBuffer> buffer, bool isReserveSlot)
434 {
435     (void)isReserveSlot;
436     if (buffer == nullptr || producer_ == nullptr) {
437         return SURFACE_ERROR_UNKOWN;
438     }
439     auto ret = producer_->DetachBufferFromQueue(buffer);
440     if (ret == GSERROR_OK) {
441         std::lock_guard<std::mutex> lockGuard(mutex_);
442         auto it = bufferProducerCache_.find(buffer->GetSeqNum());
443         if (it == bufferProducerCache_.end()) {
444             BLOGE("Detach buffer %{public}d, uniqueId: %{public}" PRIu64 ".", buffer->GetSeqNum(), queueId_);
445             return SURFACE_ERROR_BUFFER_NOT_INCACHE;
446         }
447         bufferProducerCache_.erase(it);
448     }
449     return ret;
450 }
451 
AttachBuffer(sptr<SurfaceBuffer> & buffer)452 GSError ProducerSurface::AttachBuffer(sptr<SurfaceBuffer>& buffer)
453 {
454     if (buffer == nullptr || producer_ == nullptr) {
455         return GSERROR_INVALID_ARGUMENTS;
456     }
457 
458     return producer_->AttachBuffer(buffer);
459 }
460 
AttachBuffer(sptr<SurfaceBuffer> & buffer,int32_t timeOut)461 GSError ProducerSurface::AttachBuffer(sptr<SurfaceBuffer>& buffer, int32_t timeOut)
462 {
463     if (buffer == nullptr || producer_ == nullptr) {
464         return GSERROR_INVALID_ARGUMENTS;
465     }
466 
467     return producer_->AttachBuffer(buffer, timeOut);
468 }
469 
DetachBuffer(sptr<SurfaceBuffer> & buffer)470 GSError ProducerSurface::DetachBuffer(sptr<SurfaceBuffer>& buffer)
471 {
472     if (buffer == nullptr || producer_ == nullptr) {
473         return GSERROR_INVALID_ARGUMENTS;
474     }
475     return producer_->DetachBuffer(buffer);
476 }
477 
RegisterSurfaceDelegator(sptr<IRemoteObject> client)478 GSError ProducerSurface::RegisterSurfaceDelegator(sptr<IRemoteObject> client)
479 {
480     if (client == nullptr) {
481         return GSERROR_INVALID_ARGUMENTS;
482     }
483     sptr<ProducerSurfaceDelegator> surfaceDelegator = ProducerSurfaceDelegator::Create();
484     if (surfaceDelegator == nullptr) {
485         BLOGE("surfaceDelegator is nullptr");
486         return GSERROR_INVALID_ARGUMENTS;
487     }
488     if (!surfaceDelegator->SetClient(client)) {
489         BLOGE("SetClient failed");
490         return GSERROR_INVALID_ARGUMENTS;
491     }
492 
493     surfaceDelegator->SetSurface(this);
494     {
495         std::lock_guard<std::mutex> lockGuard(delegatorMutex_);
496         wpPSurfaceDelegator_ = surfaceDelegator;
497     }
498 
499     auto releaseBufferCallBack = [weakThis = wptr(this)] (const sptr<SurfaceBuffer>& buffer,
500         const sptr<SyncFence>& fence) -> GSError {
501         auto pSurface = weakThis.promote();
502         if (pSurface == nullptr) {
503             BLOGE("pSurface is nullptr");
504             return GSERROR_INVALID_ARGUMENTS;
505         }
506         sptr<ProducerSurfaceDelegator> surfaceDelegator = nullptr;
507         {
508             std::lock_guard<std::mutex> lockGuard(pSurface->delegatorMutex_);
509             surfaceDelegator = pSurface->wpPSurfaceDelegator_.promote();
510         }
511         if (surfaceDelegator == nullptr) {
512             return GSERROR_INVALID_ARGUMENTS;
513         }
514         int error = surfaceDelegator->ReleaseBuffer(buffer, fence);
515         return static_cast<GSError>(error);
516     };
517     RegisterReleaseListenerBackup(releaseBufferCallBack);
518     return GSERROR_OK;
519 }
520 
GetQueueSize()521 uint32_t ProducerSurface::GetQueueSize()
522 {
523     if (producer_ == nullptr) {
524         return 0;
525     }
526     return producer_->GetQueueSize();
527 }
528 
SetQueueSize(uint32_t queueSize)529 GSError ProducerSurface::SetQueueSize(uint32_t queueSize)
530 {
531     if (producer_ == nullptr) {
532         return GSERROR_INVALID_ARGUMENTS;
533     }
534     return producer_->SetQueueSize(queueSize);
535 }
536 
GetName()537 const std::string& ProducerSurface::GetName()
538 {
539     if (!inited_.load()) {
540         BLOGW("ProducerSurface is not initialized.");
541     }
542     return name_;
543 }
544 
GetDefaultWidth()545 int32_t ProducerSurface::GetDefaultWidth()
546 {
547     if (producer_ == nullptr) {
548         return -1;
549     }
550     return producer_->GetDefaultWidth();
551 }
552 
GetDefaultHeight()553 int32_t ProducerSurface::GetDefaultHeight()
554 {
555     if (producer_ == nullptr) {
556         return -1;
557     }
558     return producer_->GetDefaultHeight();
559 }
560 
GetTransformHint() const561 GraphicTransformType ProducerSurface::GetTransformHint() const
562 {
563     std::lock_guard<std::mutex> lockGuard(mutex_);
564     return lastSetTransformHint_;
565 }
566 
SetTransformHint(GraphicTransformType transformHint)567 GSError ProducerSurface::SetTransformHint(GraphicTransformType transformHint)
568 {
569     if (producer_ == nullptr) {
570         return GSERROR_INVALID_ARGUMENTS;
571     }
572     {
573         std::lock_guard<std::mutex> lockGuard(mutex_);
574         if (lastSetTransformHint_ == transformHint) {
575             return GSERROR_OK;
576         }
577     }
578     GSError err = producer_->SetTransformHint(transformHint, initInfo_.producerId);
579     if (err == GSERROR_OK) {
580         std::lock_guard<std::mutex> lockGuard(mutex_);
581         lastSetTransformHint_ = transformHint;
582     }
583     return err;
584 }
585 
SetDefaultUsage(uint64_t usage)586 GSError ProducerSurface::SetDefaultUsage(uint64_t usage)
587 {
588     if (producer_ == nullptr) {
589         return GSERROR_INVALID_ARGUMENTS;
590     }
591     return producer_->SetDefaultUsage(usage);
592 }
593 
GetDefaultUsage()594 uint64_t ProducerSurface::GetDefaultUsage()
595 {
596     if (producer_ == nullptr) {
597         return 0;
598     }
599     return producer_->GetDefaultUsage();
600 }
601 
SetSurfaceSourceType(OHSurfaceSource sourceType)602 GSError ProducerSurface::SetSurfaceSourceType(OHSurfaceSource sourceType)
603 {
604     if (producer_ == nullptr) {
605         return GSERROR_INVALID_ARGUMENTS;
606     }
607     return producer_->SetSurfaceSourceType(sourceType);
608 }
609 
GetSurfaceSourceType() const610 OHSurfaceSource ProducerSurface::GetSurfaceSourceType() const
611 {
612     if (producer_ == nullptr) {
613         return OHSurfaceSource::OH_SURFACE_SOURCE_DEFAULT;
614     }
615     OHSurfaceSource sourceType = OHSurfaceSource::OH_SURFACE_SOURCE_DEFAULT;
616     if (producer_->GetSurfaceSourceType(sourceType) != GSERROR_OK) {
617         BLOGE("GetSurfaceSourceType failed, uniqueId: %{public}" PRIu64 ".", queueId_);
618         return OHSurfaceSource::OH_SURFACE_SOURCE_DEFAULT;
619     }
620     return sourceType;
621 }
622 
SetSurfaceAppFrameworkType(std::string appFrameworkType)623 GSError ProducerSurface::SetSurfaceAppFrameworkType(std::string appFrameworkType)
624 {
625     if (producer_ == nullptr) {
626         return GSERROR_INVALID_ARGUMENTS;
627     }
628     return producer_->SetSurfaceAppFrameworkType(appFrameworkType);
629 }
630 
GetSurfaceAppFrameworkType() const631 std::string ProducerSurface::GetSurfaceAppFrameworkType() const
632 {
633     if (producer_ == nullptr) {
634         return "";
635     }
636     std::string appFrameworkType = "";
637     if (producer_->GetSurfaceAppFrameworkType(appFrameworkType) != GSERROR_OK) {
638         BLOGE("GetSurfaceAppFrameworkType failed, uniqueId: %{public}" PRIu64 ".", queueId_);
639         return "";
640     }
641     return appFrameworkType;
642 }
643 
SetUserData(const std::string & key,const std::string & val)644 GSError ProducerSurface::SetUserData(const std::string& key, const std::string& val)
645 {
646     std::lock_guard<std::mutex> lockGuard(lockMutex_);
647     if (userData_.size() >= SURFACE_MAX_USER_DATA_COUNT) {
648         BLOGE("userData_ size out: %{public}zu, uniqueId: %{public}" PRIu64 ".", userData_.size(), queueId_);
649         return GSERROR_OUT_OF_RANGE;
650     }
651 
652     auto iterUserData = userData_.find(key);
653     if (iterUserData != userData_.end() && iterUserData->second == val) {
654         return GSERROR_API_FAILED;
655     }
656 
657     userData_[key] = val;
658     auto iter = onUserDataChange_.begin();
659     while (iter != onUserDataChange_.end()) {
660         if (iter->second != nullptr) {
661             iter->second(key, val);
662         }
663         iter++;
664     }
665 
666     return GSERROR_OK;
667 }
668 
GetUserData(const std::string & key)669 std::string ProducerSurface::GetUserData(const std::string& key)
670 {
671     std::lock_guard<std::mutex> lockGuard(lockMutex_);
672     if (userData_.find(key) != userData_.end()) {
673         return userData_[key];
674     }
675 
676     return "";
677 }
678 
RegisterReleaseListener(OnReleaseFunc func)679 GSError ProducerSurface::RegisterReleaseListener(OnReleaseFunc func)
680 {
681     if (func == nullptr || producer_ == nullptr) {
682         return GSERROR_INVALID_ARGUMENTS;
683     }
684     sptr<IProducerListener> listener;
685     {
686         std::lock_guard<std::mutex> lockGuard(listenerMutex_);
687         listener_ = new BufferReleaseProducerListener(func);
688         listener = listener_;
689     }
690     return producer_->RegisterReleaseListener(listener);
691 }
692 
RegisterReleaseListener(OnReleaseFuncWithFence funcWithFence)693 GSError ProducerSurface::RegisterReleaseListener(OnReleaseFuncWithFence funcWithFence)
694 {
695     if (funcWithFence == nullptr || producer_ == nullptr) {
696         return GSERROR_INVALID_ARGUMENTS;
697     }
698     sptr<IProducerListener> listener;
699     {
700         std::lock_guard<std::mutex> lockGuard(listenerMutex_);
701         listener_ = new BufferReleaseProducerListener(nullptr, funcWithFence);
702         listener = listener_;
703     }
704     return producer_->RegisterReleaseListener(listener);
705 }
706 
PropertyChangeCallback(const SurfaceProperty & property)707 GSError ProducerSurface::PropertyChangeCallback(const SurfaceProperty& property)
708 {
709     std::lock_guard<std::mutex> lockGuard(mutex_);
710     lastSetTransformHint_ = property.transformHint;
711     return GSERROR_OK;
712 }
713 
ResetPropertyListenerInner(uint64_t producerId)714 GSError ProducerSurface::ResetPropertyListenerInner(uint64_t producerId)
715 {
716     if (producer_ == nullptr) {
717         return GSERROR_INVALID_ARGUMENTS;
718     }
719     {
720         std::lock_guard<std::mutex> lockGuard(listenerMutex_);
721         if (initInfo_.propertyListener != nullptr) {
722             initInfo_.propertyListener->ResetReleaseFunc();
723         }
724     }
725     return producer_->UnRegisterPropertyListener(producerId);
726 }
727 
RegisterReleaseListenerBackup(OnReleaseFuncWithFence funcWithFence)728 GSError ProducerSurface::RegisterReleaseListenerBackup(OnReleaseFuncWithFence funcWithFence)
729 {
730     if (funcWithFence == nullptr || producer_ == nullptr) {
731         return GSERROR_INVALID_ARGUMENTS;
732     }
733     sptr<IProducerListener> listener;
734     {
735         std::lock_guard<std::mutex> lockGuard(listenerMutex_);
736         listenerBackup_ = new BufferReleaseProducerListener(nullptr, funcWithFence);
737         listener = listenerBackup_;
738     }
739     return producer_->RegisterReleaseListenerBackup(listener);
740 }
741 
UnRegisterReleaseListener()742 GSError ProducerSurface::UnRegisterReleaseListener()
743 {
744     if (producer_ == nullptr) {
745         return GSERROR_INVALID_ARGUMENTS;
746     }
747     {
748         std::lock_guard<std::mutex> lockGuard(listenerMutex_);
749         if (listener_ != nullptr) {
750             listener_->ResetReleaseFunc();
751         }
752     }
753     return producer_->UnRegisterReleaseListener();
754 }
755 
UnRegisterReleaseListenerBackup()756 GSError ProducerSurface::UnRegisterReleaseListenerBackup()
757 {
758     if (producer_ == nullptr) {
759         return GSERROR_INVALID_ARGUMENTS;
760     }
761     {
762         std::lock_guard<std::mutex> lockGuard(delegatorMutex_);
763         wpPSurfaceDelegator_ = nullptr;
764     }
765     {
766         std::lock_guard<std::mutex> lockGuard(listenerMutex_);
767         if (listenerBackup_ != nullptr) {
768             listenerBackup_->ResetReleaseFunc();
769         }
770     }
771     return producer_->UnRegisterReleaseListenerBackup();
772 }
773 
RegisterUserDataChangeListener(const std::string & funcName,OnUserDataChangeFunc func)774 GSError ProducerSurface::RegisterUserDataChangeListener(const std::string& funcName, OnUserDataChangeFunc func)
775 {
776     if (func == nullptr) {
777         return GSERROR_INVALID_ARGUMENTS;
778     }
779     std::lock_guard<std::mutex> lockGuard(lockMutex_);
780     if (onUserDataChange_.find(funcName) != onUserDataChange_.end()) {
781         BLOGD("already register func: %{public}s, uniqueId: %{public}" PRIu64 ".",
782             funcName.c_str(), queueId_);
783         return GSERROR_INVALID_ARGUMENTS;
784     }
785 
786     onUserDataChange_[funcName] = func;
787     return GSERROR_OK;
788 }
789 
UnRegisterUserDataChangeListener(const std::string & funcName)790 GSError ProducerSurface::UnRegisterUserDataChangeListener(const std::string& funcName)
791 {
792     std::lock_guard<std::mutex> lockGuard(lockMutex_);
793     if (onUserDataChange_.erase(funcName) == 0) {
794         BLOGD("no register funcName: %{public}s, uniqueId: %{public}" PRIu64 ".", funcName.c_str(), queueId_);
795         return GSERROR_INVALID_ARGUMENTS;
796     }
797 
798     return GSERROR_OK;
799 }
800 
ClearUserDataChangeListener()801 GSError ProducerSurface::ClearUserDataChangeListener()
802 {
803     std::lock_guard<std::mutex> lockGuard(lockMutex_);
804     onUserDataChange_.clear();
805     return GSERROR_OK;
806 }
807 
IsRemote()808 bool ProducerSurface::IsRemote()
809 {
810     if (producer_ == nullptr || producer_->AsObject() == nullptr) {
811         return false;
812     }
813     return producer_->AsObject()->IsProxyObject();
814 }
815 
CleanAllLocked(uint32_t * bufSeqNum)816 void ProducerSurface::CleanAllLocked(uint32_t *bufSeqNum)
817 {
818     if (bufSeqNum && bufferProducerCache_.find(*bufSeqNum) != bufferProducerCache_.end()) {
819         preCacheBuffer_ = bufferProducerCache_[*bufSeqNum];
820     }
821     bufferProducerCache_.clear();
822     auto spNativeWindow = wpNativeWindow_.promote();
823     if (spNativeWindow != nullptr) {
824         std::lock_guard<std::mutex> lockGuard(spNativeWindow->mutex_);
825         auto& bufferCache = spNativeWindow->bufferCache_;
826         for (auto& [seqNum, buffer] : bufferCache) {
827             NativeObjectUnreference(buffer);
828         }
829         bufferCache.clear();
830     }
831 }
832 
CleanCacheLocked(bool cleanAll)833 GSError ProducerSurface::CleanCacheLocked(bool cleanAll)
834 {
835     if (producer_ == nullptr) {
836         return GSERROR_INVALID_ARGUMENTS;
837     }
838     uint32_t bufSeqNum = 0;
839     GSError ret = producer_->CleanCache(cleanAll, &bufSeqNum);
840     CleanAllLocked(&bufSeqNum);
841     if (cleanAll) {
842         preCacheBuffer_ = nullptr;
843     }
844     return ret;
845 }
846 
CleanCache(bool cleanAll)847 GSError ProducerSurface::CleanCache(bool cleanAll)
848 {
849     std::lock_guard<std::mutex> lockGuard(mutex_);
850     return CleanCacheLocked(cleanAll);
851 }
852 
GoBackground()853 GSError ProducerSurface::GoBackground()
854 {
855     if (producer_ == nullptr) {
856         return GSERROR_INVALID_ARGUMENTS;
857     }
858     {
859         std::lock_guard<std::mutex> lockGuard(mutex_);
860         CleanAllLocked(nullptr);
861     }
862     return producer_->GoBackground();
863 }
864 
GetUniqueId() const865 uint64_t ProducerSurface::GetUniqueId() const
866 {
867     if (!inited_.load()) {
868         BLOGW("ProducerSurface is not initialized.");
869     }
870     return queueId_;
871 }
872 
SetTransform(GraphicTransformType transform)873 GSError ProducerSurface::SetTransform(GraphicTransformType transform)
874 {
875     if (producer_ == nullptr) {
876         return GSERROR_INVALID_ARGUMENTS;
877     }
878     return producer_->SetTransform(transform);
879 }
880 
GetTransform() const881 GraphicTransformType ProducerSurface::GetTransform() const
882 {
883     if (producer_ == nullptr) {
884         return GraphicTransformType::GRAPHIC_ROTATE_BUTT;
885     }
886     GraphicTransformType transform = GraphicTransformType::GRAPHIC_ROTATE_BUTT;
887     if (producer_->GetTransform(transform) != GSERROR_OK) {
888         BLOGE("GetTransform failed, uniqueId: %{public}" PRIu64 ".", queueId_);
889         return GraphicTransformType::GRAPHIC_ROTATE_BUTT;
890     }
891     return transform;
892 }
893 
Connect()894 GSError ProducerSurface::Connect()
895 {
896     if (producer_ == nullptr) {
897         return GSERROR_INVALID_ARGUMENTS;
898     }
899     std::lock_guard<std::mutex> lockGuard(mutex_);
900     if (!isDisconnected_) {
901         BLOGE("Surface has been connect, uniqueId: %{public}" PRIu64 ".", queueId_);
902         return SURFACE_ERROR_CONSUMER_IS_CONNECTED;
903     }
904     GSError ret = producer_->Connect();
905     if (ret == GSERROR_OK) {
906         isDisconnected_ = false;
907     }
908     return ret;
909 }
910 
Disconnect()911 GSError ProducerSurface::Disconnect()
912 {
913     if (producer_ == nullptr) {
914         return GSERROR_INVALID_ARGUMENTS;
915     }
916     std::lock_guard<std::mutex> lockGuard(mutex_);
917     if (isDisconnected_) {
918         BLOGD("Surface is disconnect, uniqueId: %{public}" PRIu64 ".", queueId_);
919         return SURFACE_ERROR_CONSUMER_DISCONNECTED;
920     }
921     uint32_t bufSeqNum = 0;
922     GSError ret = producer_->Disconnect(&bufSeqNum);
923     if (ret == GSERROR_OK) {
924         isDisconnected_ = true;
925     }
926     CleanAllLocked(&bufSeqNum);
927     return ret;
928 }
929 
ConnectStrictly()930 GSError ProducerSurface::ConnectStrictly()
931 {
932     if (producer_ == nullptr) {
933         return GSERROR_INVALID_ARGUMENTS;
934     }
935     std::lock_guard<std::mutex> lockGuard(mutex_);
936     GSError ret = producer_->ConnectStrictly();
937     return ret;
938 }
939 
DisconnectStrictly()940 GSError ProducerSurface::DisconnectStrictly()
941 {
942     if (producer_ == nullptr) {
943         return GSERROR_INVALID_ARGUMENTS;
944     }
945     std::lock_guard<std::mutex> lockGuard(mutex_);
946     GSError ret = producer_->DisconnectStrictly();
947     return ret;
948 }
949 
SetScalingMode(uint32_t sequence,ScalingMode scalingMode)950 GSError ProducerSurface::SetScalingMode(uint32_t sequence, ScalingMode scalingMode)
951 {
952     if (producer_ == nullptr || scalingMode < ScalingMode::SCALING_MODE_FREEZE ||
953         scalingMode > ScalingMode::SCALING_MODE_SCALE_FIT) {
954         return GSERROR_INVALID_ARGUMENTS;
955     }
956     return producer_->SetScalingMode(sequence, scalingMode);
957 }
958 
SetScalingMode(ScalingMode scalingMode)959 GSError ProducerSurface::SetScalingMode(ScalingMode scalingMode)
960 {
961     if (producer_ == nullptr || scalingMode < ScalingMode::SCALING_MODE_FREEZE ||
962         scalingMode > ScalingMode::SCALING_MODE_SCALE_FIT) {
963         return GSERROR_INVALID_ARGUMENTS;
964     }
965     return producer_->SetScalingMode(scalingMode);
966 }
967 
SetBufferHold(bool hold)968 void ProducerSurface::SetBufferHold(bool hold)
969 {
970     if (producer_ == nullptr) {
971         return;
972     }
973     producer_->SetBufferHold(hold);
974 }
975 
SetBufferReallocFlag(bool flag)976 GSError ProducerSurface::SetBufferReallocFlag(bool flag)
977 {
978     if (producer_ == nullptr) {
979         return GSERROR_INVALID_ARGUMENTS;
980     }
981     return producer_->SetBufferReallocFlag(flag);
982 }
983 
SetMetaData(uint32_t sequence,const std::vector<GraphicHDRMetaData> & metaData)984 GSError ProducerSurface::SetMetaData(uint32_t sequence, const std::vector<GraphicHDRMetaData>& metaData)
985 {
986     if (producer_ == nullptr || metaData.size() == 0) {
987         return GSERROR_INVALID_ARGUMENTS;
988     }
989     return producer_->SetMetaData(sequence, metaData);
990 }
991 
SetMetaDataSet(uint32_t sequence,GraphicHDRMetadataKey key,const std::vector<uint8_t> & metaData)992 GSError ProducerSurface::SetMetaDataSet(uint32_t sequence, GraphicHDRMetadataKey key,
993                                         const std::vector<uint8_t>& metaData)
994 {
995     if (producer_ == nullptr || key < GraphicHDRMetadataKey::GRAPHIC_MATAKEY_RED_PRIMARY_X ||
996         key > GraphicHDRMetadataKey::GRAPHIC_MATAKEY_HDR_VIVID || metaData.size() == 0) {
997         return GSERROR_INVALID_ARGUMENTS;
998     }
999     return producer_->SetMetaDataSet(sequence, key, metaData);
1000 }
1001 
SetTunnelHandle(const GraphicExtDataHandle * handle)1002 GSError ProducerSurface::SetTunnelHandle(const GraphicExtDataHandle *handle)
1003 {
1004     if (producer_ == nullptr) {
1005         return GSERROR_INVALID_ARGUMENTS;
1006     }
1007     return producer_->SetTunnelHandle(handle);
1008 }
1009 
GetPresentTimestamp(uint32_t sequence,GraphicPresentTimestampType type,int64_t & time) const1010 GSError ProducerSurface::GetPresentTimestamp(uint32_t sequence, GraphicPresentTimestampType type,
1011                                              int64_t& time) const
1012 {
1013     if (producer_ == nullptr || type <= GraphicPresentTimestampType::GRAPHIC_DISPLAY_PTS_UNSUPPORTED ||
1014         type > GraphicPresentTimestampType::GRAPHIC_DISPLAY_PTS_TIMESTAMP) {
1015         return GSERROR_INVALID_ARGUMENTS;
1016     }
1017     return producer_->GetPresentTimestamp(sequence, type, time);
1018 }
1019 
SetWptrNativeWindowToPSurface(void * nativeWindow)1020 GSError ProducerSurface::SetWptrNativeWindowToPSurface(void* nativeWindow)
1021 {
1022     if (nativeWindow == nullptr) {
1023         return GSERROR_INVALID_ARGUMENTS;
1024     }
1025     NativeWindow *nw = reinterpret_cast<NativeWindow *>(nativeWindow);
1026     std::lock_guard<std::mutex> lockGuard(mutex_);
1027     wpNativeWindow_ = nw;
1028     return GSERROR_OK;
1029 }
1030 
SetBufferName(const std::string & name)1031 GSError ProducerSurface::SetBufferName(const std::string &name)
1032 {
1033     bufferName_ = name;
1034     producer_->SetBufferName(name);
1035     return GSERROR_OK;
1036 }
1037 
SetRequestWidthAndHeight(int32_t width,int32_t height)1038 void ProducerSurface::SetRequestWidthAndHeight(int32_t width, int32_t height)
1039 {
1040     std::lock_guard<std::mutex> lockGuard(mutex_);
1041     requestWidth_ = width;
1042     requestHeight_ = height;
1043 }
1044 
GetRequestWidth()1045 int32_t ProducerSurface::GetRequestWidth()
1046 {
1047     std::lock_guard<std::mutex> lockGuard(mutex_);
1048     return requestWidth_;
1049 }
1050 
GetRequestHeight()1051 int32_t ProducerSurface::GetRequestHeight()
1052 {
1053     std::lock_guard<std::mutex> lockGuard(mutex_);
1054     return requestHeight_;
1055 }
1056 
SetWindowConfig(const BufferRequestConfig & config)1057 void ProducerSurface::SetWindowConfig(const BufferRequestConfig& config)
1058 {
1059     std::lock_guard<std::mutex> lockGuard(mutex_);
1060     windowConfig_ = config;
1061 }
1062 
SetWindowConfigWidthAndHeight(int32_t width,int32_t height)1063 void ProducerSurface::SetWindowConfigWidthAndHeight(int32_t width, int32_t height)
1064 {
1065     std::lock_guard<std::mutex> lockGuard(mutex_);
1066     windowConfig_.width = width;
1067     windowConfig_.height = height;
1068 }
1069 
SetWindowConfigStride(int32_t stride)1070 void ProducerSurface::SetWindowConfigStride(int32_t stride)
1071 {
1072     std::lock_guard<std::mutex> lockGuard(mutex_);
1073     windowConfig_.strideAlignment = stride;
1074 }
1075 
SetWindowConfigFormat(int32_t format)1076 void ProducerSurface::SetWindowConfigFormat(int32_t format)
1077 {
1078     std::lock_guard<std::mutex> lockGuard(mutex_);
1079     windowConfig_.format = format;
1080 }
1081 
SetWindowConfigUsage(uint64_t usage)1082 void ProducerSurface::SetWindowConfigUsage(uint64_t usage)
1083 {
1084     std::lock_guard<std::mutex> lockGuard(mutex_);
1085     windowConfig_.usage = usage;
1086 }
1087 
SetWindowConfigTimeout(int32_t timeout)1088 void ProducerSurface::SetWindowConfigTimeout(int32_t timeout)
1089 {
1090     std::lock_guard<std::mutex> lockGuard(mutex_);
1091     windowConfig_.timeout = timeout;
1092 }
1093 
SetWindowConfigColorGamut(GraphicColorGamut colorGamut)1094 void ProducerSurface::SetWindowConfigColorGamut(GraphicColorGamut colorGamut)
1095 {
1096     std::lock_guard<std::mutex> lockGuard(mutex_);
1097     windowConfig_.colorGamut = colorGamut;
1098 }
1099 
SetWindowConfigTransform(GraphicTransformType transform)1100 void ProducerSurface::SetWindowConfigTransform(GraphicTransformType transform)
1101 {
1102     std::lock_guard<std::mutex> lockGuard(mutex_);
1103     windowConfig_.transform = transform;
1104 }
1105 
GetWindowConfig()1106 BufferRequestConfig ProducerSurface::GetWindowConfig()
1107 {
1108     std::lock_guard<std::mutex> lockGuard(mutex_);
1109     return windowConfig_;
1110 }
1111 
SetHdrWhitePointBrightness(float brightness)1112 GSError ProducerSurface::SetHdrWhitePointBrightness(float brightness)
1113 {
1114     if (producer_ == nullptr) {
1115         return GSERROR_INVALID_ARGUMENTS;
1116     }
1117     if (brightness < 0.0 || brightness > 1.0) {
1118         BLOGE("brightness:%{public}f, uniqueId: %{public}" PRIu64 ".", brightness, queueId_);
1119         return GSERROR_INVALID_ARGUMENTS;
1120     }
1121     return producer_->SetHdrWhitePointBrightness(brightness);
1122 }
1123 
SetSdrWhitePointBrightness(float brightness)1124 GSError ProducerSurface::SetSdrWhitePointBrightness(float brightness)
1125 {
1126     if (producer_ == nullptr) {
1127         return GSERROR_INVALID_ARGUMENTS;
1128     }
1129     if (brightness < 0.0 || brightness > 1.0) {
1130         BLOGE("brightness:%{public}f, uniqueId: %{public}" PRIu64 ".", brightness, queueId_);
1131         return GSERROR_INVALID_ARGUMENTS;
1132     }
1133     return producer_->SetSdrWhitePointBrightness(brightness);
1134 }
1135 
AcquireLastFlushedBuffer(sptr<SurfaceBuffer> & buffer,sptr<SyncFence> & fence,float matrix[16],uint32_t matrixSize,bool isUseNewMatrix)1136 GSError ProducerSurface::AcquireLastFlushedBuffer(sptr<SurfaceBuffer>& buffer, sptr<SyncFence>& fence,
1137     float matrix[16], uint32_t matrixSize, bool isUseNewMatrix)
1138 {
1139     if (producer_ == nullptr) {
1140         return GSERROR_INVALID_ARGUMENTS;
1141     }
1142     return producer_->AcquireLastFlushedBuffer(buffer, fence, matrix, matrixSize, isUseNewMatrix);
1143 }
1144 
ReleaseLastFlushedBuffer(sptr<SurfaceBuffer> buffer)1145 GSError ProducerSurface::ReleaseLastFlushedBuffer(sptr<SurfaceBuffer> buffer)
1146 {
1147     if (buffer == nullptr || producer_ == nullptr) {
1148         return GSERROR_INVALID_ARGUMENTS;
1149     }
1150     return producer_->ReleaseLastFlushedBuffer(buffer->GetSeqNum());
1151 }
1152 
SetGlobalAlpha(int32_t alpha)1153 GSError ProducerSurface::SetGlobalAlpha(int32_t alpha)
1154 {
1155     if (producer_ == nullptr || alpha < FORCE_GLOBAL_ALPHA_MIN || alpha > FORCE_GLOBAL_ALPHA_MAX) {
1156         BLOGE("Invalid producer global alpha value: %{public}d, queueId: %{public}" PRIu64 ".", alpha, queueId_);
1157         return GSERROR_INVALID_ARGUMENTS;
1158     }
1159     return producer_->SetGlobalAlpha(alpha);
1160 }
1161 
SetRequestBufferNoblockMode(bool noblock)1162 GSError ProducerSurface::SetRequestBufferNoblockMode(bool noblock)
1163 {
1164     if (producer_ == nullptr) {
1165         return GSERROR_INVALID_ARGUMENTS;
1166     }
1167     return producer_->SetRequestBufferNoblockMode(noblock);
1168 }
1169 
UpdateCacheLocked(sptr<BufferExtraData> & bedataimpl,IBufferProducer::RequestBufferReturnValue & retval,BufferRequestConfig & config)1170 GSError ProducerSurface::UpdateCacheLocked(sptr<BufferExtraData>& bedataimpl,
1171     IBufferProducer::RequestBufferReturnValue& retval, BufferRequestConfig& config)
1172 {
1173     // add cache
1174     if (retval.buffer == nullptr) {
1175         auto it = bufferProducerCache_.find(retval.sequence);
1176         if (it == bufferProducerCache_.end()) {
1177             DeleteCacheBufferLocked(bedataimpl, retval, config);
1178             BLOGE("cache not find buffer(%{public}u), uniqueId: %{public}" PRIu64 ".", retval.sequence, queueId_);
1179             return SURFACE_ERROR_UNKOWN;
1180         } else {
1181             retval.buffer = it->second;
1182         }
1183     }
1184     bufferProducerCache_.erase(retval.sequence);
1185     SetBufferConfigLocked(bedataimpl, retval, config);
1186     DeleteCacheBufferLocked(bedataimpl, retval, config);
1187     return SURFACE_ERROR_OK;
1188 }
1189 
RequestAndDetachBuffer(sptr<SurfaceBuffer> & buffer,sptr<SyncFence> & fence,BufferRequestConfig & config)1190 GSError ProducerSurface::RequestAndDetachBuffer(sptr<SurfaceBuffer>& buffer, sptr<SyncFence>& fence,
1191                                                 BufferRequestConfig& config)
1192 {
1193     if (producer_ == nullptr) {
1194         return GSERROR_INVALID_ARGUMENTS;
1195     }
1196     IBufferProducer::RequestBufferReturnValue retval;
1197     sptr<BufferExtraData> bedataimpl = new BufferExtraDataImpl;
1198 
1199     std::lock_guard<std::mutex> lockGuard(mutex_);
1200     GSError ret = producer_->RequestAndDetachBuffer(config, bedataimpl, retval);
1201     if (ret != GSERROR_OK) {
1202         if (ret == GSERROR_NO_CONSUMER) {
1203             CleanCacheLocked(false);
1204         }
1205         /**
1206          * if server is connected, but result is failed.
1207          * client needs to synchronize status.
1208          */
1209         if (retval.isConnected) {
1210             isDisconnected_ = false;
1211         }
1212         BLOGD("RequestAndDetachBuffer ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
1213         return ret;
1214     }
1215     isDisconnected_ = false;
1216     UpdateCacheLocked(bedataimpl, retval, config);
1217     buffer = retval.buffer;
1218     fence = retval.fence;
1219 
1220     if (SetMetadataValue(buffer) != GSERROR_OK) {
1221         BLOGD("SetMetadataValue fail, uniqueId: %{public}" PRIu64 ".", queueId_);
1222     }
1223     return ret;
1224 }
1225 
AttachAndFlushBuffer(sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & fence,BufferFlushConfig & config,bool needMap)1226 GSError ProducerSurface::AttachAndFlushBuffer(sptr<SurfaceBuffer>& buffer, const sptr<SyncFence>& fence,
1227                                               BufferFlushConfig& config, bool needMap)
1228 {
1229     if (buffer == nullptr || fence == nullptr || producer_ == nullptr) {
1230         return GSERROR_INVALID_ARGUMENTS;
1231     }
1232 
1233     sptr<BufferExtraData> bedata = buffer->GetExtraData();
1234     if (bedata == nullptr) {
1235         return GSERROR_INVALID_ARGUMENTS;
1236     }
1237 
1238     BufferFlushConfigWithDamages configWithDamages;
1239     configWithDamages.damages.push_back(config.damage);
1240     configWithDamages.timestamp = config.timestamp;
1241     configWithDamages.desiredPresentTimestamp = config.desiredPresentTimestamp;
1242 
1243     auto ret = producer_->AttachAndFlushBuffer(buffer, bedata, fence, configWithDamages, needMap);
1244     if (ret == GSERROR_OK) {
1245         std::lock_guard<std::mutex> lockGuard(mutex_);
1246         if (bufferProducerCache_.find(buffer->GetSeqNum()) != bufferProducerCache_.end()) {
1247             BLOGE("Attach buffer %{public}d, uniqueId: %{public}" PRIu64 ".", buffer->GetSeqNum(), queueId_);
1248             return SURFACE_ERROR_BUFFER_IS_INCACHE;
1249         }
1250         bufferProducerCache_[buffer->GetSeqNum()] = buffer;
1251     } else if (ret == GSERROR_NO_CONSUMER) {
1252         CleanCache();
1253         BLOGD("FlushBuffer ret: %{public}d, uniqueId: %{public}" PRIu64 ".", ret, queueId_);
1254     }
1255     return ret;
1256 }
1257 
ReleasePreCacheBuffer(int bufferCacheSize)1258 void ProducerSurface::ReleasePreCacheBuffer(int bufferCacheSize)
1259 {
1260     // client must have more than two buffer, otherwise RS can not delete the prebuffer.
1261     // Because RS has two buffer(pre and cur).
1262     const int deletePreCacheBufferThreshold = 2; // 2 is delete threshold.
1263     if (bufferCacheSize >= deletePreCacheBufferThreshold) {
1264         preCacheBuffer_ = nullptr;
1265     }
1266 }
1267 
GetCycleBuffersNumber(uint32_t & cycleBuffersNumber)1268 GSError ProducerSurface::GetCycleBuffersNumber(uint32_t& cycleBuffersNumber)
1269 {
1270     if (producer_ == nullptr) {
1271         return SURFACE_ERROR_UNKOWN;
1272     }
1273     return producer_->GetCycleBuffersNumber(cycleBuffersNumber);
1274 }
1275 
SetCycleBuffersNumber(uint32_t cycleBuffersNumber)1276 GSError ProducerSurface::SetCycleBuffersNumber(uint32_t cycleBuffersNumber)
1277 {
1278     if (producer_ == nullptr) {
1279         return SURFACE_ERROR_UNKOWN;
1280     }
1281     return producer_->SetCycleBuffersNumber(cycleBuffersNumber);
1282 }
1283 
SetFrameGravity(int32_t frameGravity)1284 GSError ProducerSurface::SetFrameGravity(int32_t frameGravity)
1285 {
1286     if (producer_ == nullptr) {
1287         return SURFACE_ERROR_UNKOWN;
1288     }
1289     return producer_->SetFrameGravity(frameGravity);
1290 }
1291 
SetFixedRotation(int32_t fixedRotation)1292 GSError ProducerSurface::SetFixedRotation(int32_t fixedRotation)
1293 {
1294     if (producer_ == nullptr) {
1295         return SURFACE_ERROR_UNKOWN;
1296     }
1297     return producer_->SetFixedRotation(fixedRotation);
1298 }
1299 
PreAllocBuffers(const BufferRequestConfig & config,uint32_t allocBufferCount)1300 GSError ProducerSurface::PreAllocBuffers(const BufferRequestConfig &config, uint32_t allocBufferCount)
1301 {
1302     if (producer_ == nullptr) {
1303         return GSERROR_INVALID_ARGUMENTS;
1304     }
1305     return producer_->PreAllocBuffers(config, allocBufferCount);
1306 }
1307 
ProducerSurfaceCancelBufferLocked(sptr<SurfaceBuffer> & buffer)1308 GSError ProducerSurface::ProducerSurfaceCancelBufferLocked(sptr<SurfaceBuffer>& buffer)
1309 {
1310     sptr<BufferExtraData> bedata = buffer->GetExtraData();
1311     if (bedata == nullptr) {
1312         return SURFACE_ERROR_UNKOWN;
1313     }
1314     auto ret = producer_->CancelBuffer(buffer->GetSeqNum(), bedata);
1315     if (ret == GSERROR_OK) {
1316         mLockedBuffer_ = nullptr;
1317         region_.rectNumber = 0;
1318         delete[] region_.rects;
1319         region_.rects = nullptr;
1320     }
1321     return ret;
1322 }
1323 
ProducerSurfaceLockBuffer(BufferRequestConfig & config,Region region,sptr<SurfaceBuffer> & buffer)1324 GSError ProducerSurface::ProducerSurfaceLockBuffer(BufferRequestConfig &config, Region region,
1325                                                    sptr<SurfaceBuffer>& buffer)
1326 {
1327     SURFACE_TRACE_NAME_FMT("ProducerSurfaceLockBuffer width: %u, height: %u", config.width, config.height);
1328     std::lock_guard<std::mutex> lockGuard(mutex_);
1329     // native buffer is locked
1330     if (mLockedBuffer_ != nullptr) {
1331         buffer = nullptr;
1332         return GSERROR_INVALID_OPERATING;
1333     }
1334     config.usage |= (BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE);
1335     sptr<SyncFence> syncFence = SyncFence::InvalidFence();
1336     auto ret = RequestBufferLocked(buffer, syncFence, config);
1337     if (ret != GSERROR_OK) {
1338         buffer = nullptr;
1339         BLOGE("RequestBuffer failed, ret:%{public}d, uniqueId: %{public}" PRIu64 ".", ret, GetUniqueId());
1340         return ret;
1341     }
1342     SURFACE_TRACE_NAME_FMT("wait syncFence, bufferId: %u, uniqueId: %u", buffer->GetSeqNum(), GetUniqueId());
1343     syncFence->Wait(-1);
1344     ret = buffer->Map();
1345     if (ret != GSERROR_OK) {
1346         auto tmpRet = ProducerSurfaceCancelBufferLocked(buffer);
1347         BLOGE("Map failed, ret:%{public}d, cancelBuffer tmpRet:%{public}d,"
1348             "uniqueId: %{public}" PRIu64 ".", ret, tmpRet, GetUniqueId());
1349         buffer = nullptr;
1350         return ret;
1351     }
1352     mLockedBuffer_ = buffer;
1353     region_.rectNumber = region.rectNumber;
1354     if (region.rectNumber != 0 && region.rects != nullptr) {
1355         region_.rects = new Region::Rect[region.rectNumber];
1356         auto tmpRet = memcpy_s(region_.rects, region.rectNumber * sizeof(Region::Rect),
1357                                region.rects, region.rectNumber * sizeof(Region::Rect));
1358         if (tmpRet != EOK) {
1359             auto tmpRet = ProducerSurfaceCancelBufferLocked(buffer);
1360             BLOGE("memcpy_s failed, ret:%{public}d, cancelBuffer tmpRet:%{public}d,"
1361                 "uniqueId: %{public}" PRIu64 ".", ret, tmpRet, GetUniqueId());
1362             buffer = nullptr;
1363             return SURFACE_ERROR_UNKOWN;
1364         }
1365     }
1366 
1367     return SURFACE_ERROR_OK;
1368 }
1369 
ProducerSurfaceUnlockAndFlushBuffer()1370 GSError ProducerSurface::ProducerSurfaceUnlockAndFlushBuffer()
1371 {
1372     std::lock_guard<std::mutex> lockGuard(mutex_);
1373     // native buffer is unlocked
1374     if (mLockedBuffer_ == nullptr) {
1375         return GSERROR_INVALID_OPERATING;
1376     }
1377     OHOS::BufferFlushConfigWithDamages config;
1378     if ((region_.rectNumber <= DAMAGES_MAX_SIZE) && (region_.rectNumber > 0) && (region_.rects != nullptr)) {
1379         config.damages.reserve(region_.rectNumber);
1380         for (int32_t i = 0; i < region_.rectNumber; i++) {
1381             OHOS::Rect damage = {
1382                 .x = region_.rects[i].x,
1383                 .y = region_.rects[i].y,
1384                 .w = static_cast<int32_t>(region_.rects[i].w),
1385                 .h = static_cast<int32_t>(region_.rects[i].h),
1386             };
1387             config.damages.emplace_back(damage);
1388         }
1389     } else {
1390         config.damages.reserve(1);
1391         OHOS::Rect damage = {.x = 0, .y = 0, .w = windowConfig_.width, .h = windowConfig_.height};
1392         config.damages.emplace_back(damage);
1393     }
1394     sptr<SyncFence> acquireFence = SyncFence::InvalidFence();
1395     auto ret = FlushBuffer(mLockedBuffer_, acquireFence, config, false);
1396     if (ret != GSERROR_OK) {
1397         BLOGE("FlushBuffer failed, ret:%{public}d, uniqueId: %{public}" PRId64 ".", ret, GetUniqueId());
1398         return ret;
1399     }
1400     mLockedBuffer_ = nullptr;
1401     delete[] region_.rects;
1402     region_.rects = nullptr;
1403     return SURFACE_ERROR_OK;
1404 }
SetLppShareFd(int fd,bool state)1405 GSError ProducerSurface::SetLppShareFd(int fd, bool state)
1406 {
1407     if (producer_ == nullptr || fd < 0) {
1408         return GSERROR_INVALID_ARGUMENTS;
1409     }
1410 
1411     int lppFd = dup(fd);
1412     if (lppFd == -1) {
1413         return GSERROR_NO_MEM;
1414     }
1415     GSError ret = producer_->SetLppShareFd(lppFd, state);
1416     close(lppFd);
1417     return ret;
1418 }
1419 
SetAlphaType(GraphicAlphaType alphaType)1420 GSError ProducerSurface::SetAlphaType(GraphicAlphaType alphaType)
1421 {
1422     if (producer_ == nullptr) {
1423         return SURFACE_ERROR_UNKOWN;
1424     }
1425     return producer_->SetAlphaType(alphaType);
1426 }
1427 } // namespace OHOS
1428