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