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