| Sungtak Lee | fce527c | 2021-03-20 01:24:41 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2021 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 | //#define LOG_NDEBUG 0 | 
|  | 18 | #define LOG_TAG "C2FenceFactory" | 
|  | 19 | #include <utils/Log.h> | 
|  | 20 |  | 
|  | 21 | #include <C2FenceFactory.h> | 
|  | 22 | #include <C2SurfaceSyncObj.h> | 
|  | 23 |  | 
|  | 24 | class C2Fence::Impl { | 
|  | 25 | public: | 
|  | 26 | virtual c2_status_t wait(c2_nsecs_t timeoutNs) = 0; | 
|  | 27 |  | 
|  | 28 | virtual bool valid() const = 0; | 
|  | 29 |  | 
|  | 30 | virtual bool ready() const = 0; | 
|  | 31 |  | 
|  | 32 | virtual int fd() const = 0; | 
|  | 33 |  | 
|  | 34 | virtual bool isHW() const = 0; | 
|  | 35 |  | 
|  | 36 | virtual ~Impl() = default; | 
|  | 37 |  | 
|  | 38 | Impl() = default; | 
|  | 39 | }; | 
|  | 40 |  | 
|  | 41 | c2_status_t C2Fence::wait(c2_nsecs_t timeoutNs) { | 
|  | 42 | if (mImpl) { | 
|  | 43 | return mImpl->wait(timeoutNs); | 
|  | 44 | } | 
|  | 45 | // null fence is always signalled. | 
|  | 46 | return C2_OK; | 
|  | 47 | } | 
|  | 48 |  | 
|  | 49 | bool C2Fence::valid() const { | 
|  | 50 | if (mImpl) { | 
|  | 51 | return mImpl->valid(); | 
|  | 52 | } | 
|  | 53 | // null fence is always valid. | 
|  | 54 | return true; | 
|  | 55 | } | 
|  | 56 |  | 
|  | 57 | bool C2Fence::ready() const { | 
|  | 58 | if (mImpl) { | 
|  | 59 | return mImpl->ready(); | 
|  | 60 | } | 
|  | 61 | // null fence is always signalled. | 
|  | 62 | return true; | 
|  | 63 | } | 
|  | 64 |  | 
|  | 65 | int C2Fence::fd() const { | 
|  | 66 | if (mImpl) { | 
|  | 67 | return mImpl->fd(); | 
|  | 68 | } | 
|  | 69 | // null fence does not have fd. | 
|  | 70 | return -1; | 
|  | 71 | } | 
|  | 72 |  | 
|  | 73 | bool C2Fence::isHW() const { | 
|  | 74 | if (mImpl) { | 
|  | 75 | return mImpl->isHW(); | 
|  | 76 | } | 
|  | 77 | return false; | 
|  | 78 | } | 
|  | 79 |  | 
|  | 80 | /** | 
|  | 81 | * Fence implementation for C2BufferQueueBlockPool based block allocation. | 
|  | 82 | * The implementation supports all C2Fence interface except fd(). | 
|  | 83 | */ | 
|  | 84 | class _C2FenceFactory::SurfaceFenceImpl: public C2Fence::Impl { | 
|  | 85 | public: | 
|  | 86 | virtual c2_status_t wait(c2_nsecs_t timeoutNs) { | 
|  | 87 | if (mPtr) { | 
|  | 88 | return mPtr->waitForChange(mWaitId, timeoutNs); | 
|  | 89 | } | 
|  | 90 | return C2_OK; | 
|  | 91 | } | 
|  | 92 |  | 
|  | 93 | virtual bool valid() const { | 
|  | 94 | return mPtr; | 
|  | 95 | } | 
|  | 96 |  | 
|  | 97 | virtual bool ready() const { | 
|  | 98 | uint32_t status; | 
|  | 99 | if (mPtr) { | 
|  | 100 | mPtr->lock(); | 
|  | 101 | status = mPtr->getWaitIdLocked(); | 
|  | 102 | mPtr->unlock(); | 
|  | 103 |  | 
|  | 104 | return status != mWaitId; | 
|  | 105 | } | 
|  | 106 | return true; | 
|  | 107 | } | 
|  | 108 |  | 
|  | 109 | virtual int fd() const { | 
|  | 110 | // does not support fd, since this is shared mem and futex based | 
|  | 111 | return -1; | 
|  | 112 | } | 
|  | 113 |  | 
|  | 114 | virtual bool isHW() const { | 
|  | 115 | return false; | 
|  | 116 | } | 
|  | 117 |  | 
|  | 118 | virtual ~SurfaceFenceImpl() {}; | 
|  | 119 |  | 
|  | 120 | SurfaceFenceImpl(std::shared_ptr<C2SurfaceSyncMemory> syncMem, uint32_t waitId) : | 
|  | 121 | mSyncMem(syncMem), | 
|  | 122 | mPtr(syncMem ? syncMem->mem() : nullptr), | 
|  | 123 | mWaitId(syncMem ? waitId : 0) {} | 
|  | 124 | private: | 
|  | 125 | const std::shared_ptr<const C2SurfaceSyncMemory> mSyncMem; // This is for life-cycle guarantee | 
|  | 126 | C2SyncVariables *const mPtr; | 
|  | 127 | const uint32_t mWaitId; | 
|  | 128 | }; | 
|  | 129 |  | 
|  | 130 | C2Fence::C2Fence(std::shared_ptr<Impl> impl) : mImpl(impl) {} | 
|  | 131 |  | 
|  | 132 | C2Fence _C2FenceFactory::CreateSurfaceFence( | 
|  | 133 | std::shared_ptr<C2SurfaceSyncMemory> syncMem, | 
|  | 134 | uint32_t waitId) { | 
|  | 135 | if (syncMem) { | 
|  | 136 | C2Fence::Impl *p | 
|  | 137 | = new _C2FenceFactory::SurfaceFenceImpl(syncMem, waitId); | 
|  | 138 | if (p->valid()) { | 
|  | 139 | return C2Fence(std::shared_ptr<C2Fence::Impl>(p)); | 
|  | 140 | } else { | 
|  | 141 | delete p; | 
|  | 142 | } | 
|  | 143 | } | 
|  | 144 | return C2Fence(); | 
|  | 145 | } |