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 FRAME_RENDER_TRACKER_H_ 18 19 #define FRAME_RENDER_TRACKER_H_ 20 21 #include <utils/RefBase.h> 22 #include <utils/Timers.h> 23 24 #include <media/stagefright/foundation/ADebug.h> 25 #include <media/stagefright/foundation/AString.h> 26 #include <ui/Fence.h> 27 #include <ui/GraphicBuffer.h> 28 29 #include <list> 30 31 struct ANativeWindowBuffer; 32 33 namespace android { 34 35 // Tracks the render information about a frame. Frames go through several states while 36 // the render information is tracked: 37 // 38 // 1. queued frame: mMediaTime and mGraphicBuffer are set for the frame. mFence is the 39 // queue fence (read fence). mIndex is negative, and mRenderTimeNs is invalid. 40 // Key characteristics: mFence is not NULL and mIndex is negative. 41 // 42 // 2. dequeued frame: mFence is updated with the dequeue fence (write fence). mIndex is set. 43 // Key characteristics: mFence is not NULL and mIndex is non-negative. mRenderTime is still 44 // invalid. 45 // 46 // 3. rendered frame or frame: mFence is cleared, mRenderTimeNs is set. 47 // Key characteristics: mFence is NULL. 48 // 49 struct RenderedFrameInfo { 50 // set by client during onFrameQueued or onFrameRendered getMediaTimeUsRenderedFrameInfo51 int64_t getMediaTimeUs() const { return mMediaTimeUs; } 52 53 // -1 if frame is not yet rendered getRenderTimeNsRenderedFrameInfo54 nsecs_t getRenderTimeNs() const { return mRenderTimeNs; } 55 56 // set by client during updateRenderInfoForDequeuedBuffer; -1 otherwise getIndexRenderedFrameInfo57 ssize_t getIndex() const { return mIndex; } 58 59 // creates information for a queued frame RenderedFrameInfoRenderedFrameInfo60 RenderedFrameInfo(int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer, 61 const sp<Fence> &fence) 62 : mMediaTimeUs(mediaTimeUs), 63 mRenderTimeNs(-1), 64 mIndex(-1), 65 mGraphicBuffer(graphicBuffer), 66 mFence(fence) { 67 } 68 69 // creates information for a frame rendered on a tunneled surface RenderedFrameInfoRenderedFrameInfo70 RenderedFrameInfo(int64_t mediaTimeUs, nsecs_t renderTimeNs) 71 : mMediaTimeUs(mediaTimeUs), 72 mRenderTimeNs(renderTimeNs), 73 mIndex(-1), 74 mGraphicBuffer(NULL), 75 mFence(NULL) { 76 } 77 78 private: 79 int64_t mMediaTimeUs; 80 nsecs_t mRenderTimeNs; 81 ssize_t mIndex; // to be used by client 82 sp<GraphicBuffer> mGraphicBuffer; 83 sp<Fence> mFence; 84 85 friend struct FrameRenderTracker; 86 }; 87 88 struct FrameRenderTracker { 89 typedef RenderedFrameInfo Info; 90 91 FrameRenderTracker(); 92 93 void setComponentName(const AString &componentName); 94 95 // clears all tracked frames, and resets last render time 96 void clear(nsecs_t lastRenderTimeNs); 97 98 // called when |graphicBuffer| corresponding to |mediaTimeUs| is 99 // queued to the output surface using |fence|. 100 void onFrameQueued( 101 int64_t mediaTimeUs, const sp<GraphicBuffer> &graphicBuffer, const sp<Fence> &fence); 102 103 // Called when we have dequeued a buffer |buf| from the native window to track render info. 104 // |fenceFd| is the dequeue fence, and |index| is a positive buffer ID to be usable by the 105 // client to track this render info among the dequeued buffers. 106 // Returns pointer to the tracked info, or NULL if buffer is not tracked or if |index| 107 // is negative. 108 Info *updateInfoForDequeuedBuffer(ANativeWindowBuffer *buf, int fenceFd, int index); 109 110 // called when tunneled codec signals frame rendered event 111 // returns BAD_VALUE if systemNano is not monotonic. Otherwise, returns OK. 112 status_t onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano); 113 114 // Checks to see if any frames have rendered up until |until|. If |until| is NULL or not a 115 // tracked info, this method searches the entire render queue. 116 // Returns list of rendered frames up-until the frame pointed to by |until| or the first 117 // unrendered frame, as well as any dropped frames (those with invalid fence) up-until |until|. 118 // These frames are removed from the render queue. 119 // If |dropIncomplete| is true, unrendered frames up-until |until| will also be dropped from the 120 // queue, allowing all rendered framed up till then to be notified of. 121 // (This will effectively clear the render queue up-until (and including) |until|.) 122 std::list<Info> checkFencesAndGetRenderedFrames(const Info *until, bool dropIncomplete); 123 124 // Stop tracking a queued frame (e.g. if the frame has been discarded). If |info| is NULL or is 125 // not tracked, this method is a no-op. If |index| is specified, all indices larger that |index| 126 // are decremented. This is useful if the untracked frame is deleted from the frame vector. 127 void untrackFrame(const Info *info, ssize_t index = SSIZE_MAX); 128 129 void dumpRenderQueue() const; 130 131 virtual ~FrameRenderTracker(); 132 133 private: 134 135 // Render information for buffers. Regular surface buffers are queued in the order of 136 // rendering. Tunneled buffers are queued in the order of receipt. 137 std::list<Info> mRenderQueue; 138 nsecs_t mLastRenderTimeNs; 139 AString mComponentName; 140 141 DISALLOW_EVIL_CONSTRUCTORS(FrameRenderTracker); 142 }; 143 144 } // namespace android 145 146 #endif // FRAME_RENDER_TRACKER_H_ 147