xref: /aosp_15_r20/frameworks/native/include/gui/BufferReleaseChannel.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <string>
20 #include <vector>
21 
22 #include <android-base/unique_fd.h>
23 
24 #include <binder/Parcelable.h>
25 #include <gui/ITransactionCompletedListener.h>
26 #include <ui/Fence.h>
27 #include <utils/Errors.h>
28 
29 namespace android::gui {
30 
31 /**
32  * IPC wrapper to pass release fences from SurfaceFlinger to apps via a local unix domain socket.
33  */
34 class BufferReleaseChannel {
35 private:
36     class Endpoint {
37     public:
Endpoint(std::string name,android::base::unique_fd fd)38         Endpoint(std::string name, android::base::unique_fd fd)
39               : mName(std::move(name)), mFd(std::move(fd)) {}
Endpoint()40         Endpoint() {}
41 
42         Endpoint(Endpoint&&) noexcept = default;
43         Endpoint& operator=(Endpoint&&) noexcept = default;
44 
45         Endpoint(const Endpoint&) = delete;
46         void operator=(const Endpoint&) = delete;
47 
getFd()48         const android::base::unique_fd& getFd() const { return mFd; }
49 
50     protected:
51         std::string mName;
52         android::base::unique_fd mFd;
53     };
54 
55 public:
56     class ConsumerEndpoint : public Endpoint {
57     public:
ConsumerEndpoint(std::string name,android::base::unique_fd fd)58         ConsumerEndpoint(std::string name, android::base::unique_fd fd)
59               : Endpoint(std::move(name), std::move(fd)) {}
60 
61         /**
62          * Reads a release fence from the BufferReleaseChannel.
63          *
64          * Returns OK on success.
65          * Returns WOULD_BLOCK if there is no fence present.
66          * Other errors probably indicate that the channel is broken.
67          */
68         status_t readReleaseFence(ReleaseCallbackId& outReleaseCallbackId,
69                                   sp<Fence>& outReleaseFence, uint32_t& maxAcquiredBufferCount);
70 
71     private:
72         std::mutex mMutex;
73         std::vector<uint8_t> mFlattenedBuffer GUARDED_BY(mMutex);
74     };
75 
76     class ProducerEndpoint : public Endpoint, public Parcelable {
77     public:
ProducerEndpoint(std::string name,android::base::unique_fd fd)78         ProducerEndpoint(std::string name, android::base::unique_fd fd)
79               : Endpoint(std::move(name), std::move(fd)) {}
ProducerEndpoint()80         ProducerEndpoint() {}
81 
82         status_t readFromParcel(const android::Parcel* parcel) override;
83         status_t writeToParcel(android::Parcel* parcel) const override;
84 
85         status_t writeReleaseFence(const ReleaseCallbackId&, const sp<Fence>& releaseFence,
86                                    uint32_t maxAcquiredBufferCount);
87 
88     private:
89         std::vector<uint8_t> mFlattenedBuffer;
90     };
91 
92     /**
93      * Create two endpoints that make up the BufferReleaseChannel.
94      *
95      * Return OK on success.
96      */
97     static status_t open(const std::string name, std::unique_ptr<ConsumerEndpoint>& outConsumer,
98                          std::shared_ptr<ProducerEndpoint>& outProducer);
99 
100     struct Message : public Flattenable<Message> {
101         ReleaseCallbackId releaseCallbackId;
102         sp<Fence> releaseFence = Fence::NO_FENCE;
103         uint32_t maxAcquiredBufferCount;
104 
105         Message() = default;
MessageMessage106         Message(ReleaseCallbackId releaseCallbackId, sp<Fence> releaseFence,
107                 uint32_t maxAcquiredBufferCount)
108               : releaseCallbackId{releaseCallbackId},
109                 releaseFence{std::move(releaseFence)},
110                 maxAcquiredBufferCount{maxAcquiredBufferCount} {}
111 
112         // Flattenable protocol
113         size_t getFlattenedSize() const;
114 
getFdCountMessage115         size_t getFdCount() const { return releaseFence->getFdCount(); }
116 
117         status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
118 
119         status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
120 
121     private:
122         size_t getPodSize() const;
123     };
124 };
125 
126 } // namespace android::gui
127