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