1 /* 2 * Copyright 2015 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 #ifndef FIFO_FIFO_BUFFER_H 18 #define FIFO_FIFO_BUFFER_H 19 20 #include <memory> 21 #include <stdint.h> 22 23 #include "FifoControllerBase.h" 24 25 namespace android { 26 27 /** 28 * Structure that represents a region in a circular buffer that might be at the 29 * end of the array and split in two. 30 */ 31 struct WrappingBuffer { 32 enum { 33 SIZE = 2 34 }; 35 void *data[SIZE]; 36 int32_t numFrames[SIZE]; 37 }; 38 39 class FifoBuffer { 40 public: 41 explicit FifoBuffer(int32_t bytesPerFrame); 42 43 virtual ~FifoBuffer() = default; 44 45 int32_t convertFramesToBytes(fifo_frames_t frames); 46 47 fifo_frames_t read(void *destination, fifo_frames_t framesToRead); 48 49 fifo_frames_t write(const void *source, fifo_frames_t framesToWrite); 50 51 fifo_frames_t getThreshold(); 52 53 void setThreshold(fifo_frames_t threshold); 54 55 fifo_frames_t getBufferCapacityInFrames(); 56 57 /** 58 * Return pointer to available full frames in data1 and set size in numFrames1. 59 * if the data is split across the end of the FIFO then set data2 and numFrames2. 60 * Other wise set them to null 61 * @param wrappingBuffer 62 * @return total full frames available 63 */ 64 fifo_frames_t getFullDataAvailable(WrappingBuffer *wrappingBuffer); 65 66 /** 67 * Return pointer to available empty frames in data1 and set size in numFrames1. 68 * if the room is split across the end of the FIFO then set data2 and numFrames2. 69 * Other wise set them to null 70 * @param wrappingBuffer 71 * @return total empty frames available 72 */ 73 fifo_frames_t getEmptyRoomAvailable(WrappingBuffer *wrappingBuffer); 74 getBytesPerFrame()75 int32_t getBytesPerFrame() { 76 return mBytesPerFrame; 77 } 78 79 // Proxy methods for the internal FifoController 80 getReadCounter()81 fifo_counter_t getReadCounter() { 82 return mFifo->getReadCounter(); 83 } 84 setReadCounter(fifo_counter_t n)85 void setReadCounter(fifo_counter_t n) { 86 mFifo->setReadCounter(n); 87 } 88 getWriteCounter()89 fifo_counter_t getWriteCounter() { 90 return mFifo->getWriteCounter(); 91 } 92 setWriteCounter(fifo_counter_t n)93 void setWriteCounter(fifo_counter_t n) { 94 mFifo->setWriteCounter(n); 95 } 96 advanceReadIndex(fifo_frames_t numFrames)97 void advanceReadIndex(fifo_frames_t numFrames) { 98 mFifo->advanceReadIndex(numFrames); 99 } 100 advanceWriteIndex(fifo_frames_t numFrames)101 void advanceWriteIndex(fifo_frames_t numFrames) { 102 mFifo->advanceWriteIndex(numFrames); 103 } 104 getEmptyFramesAvailable()105 fifo_frames_t getEmptyFramesAvailable() { 106 return mFifo->getEmptyFramesAvailable(); 107 } 108 getFullFramesAvailable()109 fifo_frames_t getFullFramesAvailable() { 110 return mFifo->getFullFramesAvailable(); 111 } 112 113 /* 114 * This is generally only called before or after the buffer is used. 115 */ 116 void eraseMemory(); 117 118 protected: 119 120 virtual uint8_t *getStorage() const = 0; 121 122 void fillWrappingBuffer(WrappingBuffer *wrappingBuffer, 123 int32_t framesAvailable, int32_t startIndex); 124 125 const int32_t mBytesPerFrame; 126 std::unique_ptr<FifoControllerBase> mFifo{}; 127 }; 128 129 // Define two subclasses to handle the two ways that storage is allocated. 130 131 // Allocate storage internally. 132 class FifoBufferAllocated : public FifoBuffer { 133 public: 134 FifoBufferAllocated(int32_t bytesPerFrame, fifo_frames_t capacityInFrames); 135 136 private: 137 getStorage()138 uint8_t *getStorage() const override { 139 return mInternalStorage.get(); 140 }; 141 142 std::unique_ptr<uint8_t[]> mInternalStorage; 143 }; 144 145 // Allocate storage externally and pass it in. 146 class FifoBufferIndirect : public FifoBuffer { 147 public: 148 // We use raw pointers because the memory may be 149 // in the middle of an allocated block and cannot be deleted directly. 150 FifoBufferIndirect(int32_t bytesPerFrame, 151 fifo_frames_t capacityInFrames, 152 fifo_counter_t* readCounterAddress, 153 fifo_counter_t* writeCounterAddress, 154 void* dataStorageAddress); 155 156 private: 157 getStorage()158 uint8_t *getStorage() const override { 159 return mExternalStorage; 160 }; 161 162 uint8_t *mExternalStorage = nullptr; 163 }; 164 165 } // namespace android 166 167 #endif //FIFO_FIFO_BUFFER_H 168