| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1 | /* | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 2 |  * Copyright (C) 2010 The Android Open Source Project | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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_TAG "Surface" | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 18 | #define ATRACE_TAG ATRACE_TAG_GRAPHICS | 
 | 19 | //#define LOG_NDEBUG 0 | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 20 |  | 
| Mathias Agopian | 05debe1 | 2017-02-08 17:04:18 -0800 | [diff] [blame] | 21 | #include <gui/Surface.h> | 
| Mathias Agopian | b0e76f4 | 2012-03-23 14:15:44 -0700 | [diff] [blame] | 22 |  | 
| Mathias Agopian | cb496ac | 2017-05-22 14:21:00 -0700 | [diff] [blame] | 23 | #include <inttypes.h> | 
 | 24 |  | 
| Mathias Agopian | 05debe1 | 2017-02-08 17:04:18 -0800 | [diff] [blame] | 25 | #include <android/native_window.h> | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 26 |  | 
| Mathias Agopian | 9cce325 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 27 | #include <utils/Log.h> | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 28 | #include <utils/Trace.h> | 
| Rachad | 7cb0d39 | 2014-07-29 17:53:53 -0700 | [diff] [blame] | 29 | #include <utils/NativeHandle.h> | 
| Mathias Agopian | 9cce325 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 30 |  | 
| Ian Elliott | 62c48c9 | 2017-01-20 13:13:20 -0700 | [diff] [blame] | 31 | #include <ui/DisplayStatInfo.h> | 
| Courtney Goeltzenleuchter | c5b97c5 | 2017-02-26 14:47:13 -0700 | [diff] [blame] | 32 | #include <ui/Fence.h> | 
 | 33 | #include <ui/HdrCapabilities.h> | 
 | 34 | #include <ui/Region.h> | 
| Mathias Agopian | a67932f | 2011-04-20 14:20:59 -0700 | [diff] [blame] | 35 |  | 
| Mathias Agopian | 2b5dd40 | 2017-02-07 17:36:19 -0800 | [diff] [blame] | 36 | #include <gui/BufferItem.h> | 
| Dan Stoza | f0eaf25 | 2014-03-21 13:05:51 -0700 | [diff] [blame] | 37 | #include <gui/IProducerListener.h> | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 38 |  | 
| Mathias Agopian | 2b5dd40 | 2017-02-07 17:36:19 -0800 | [diff] [blame] | 39 | #include <gui/ISurfaceComposer.h> | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 40 | #include <private/gui/ComposerService.h> | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 41 |  | 
| Courtney Goeltzenleuchter | a0c93e1 | 2017-03-17 16:16:48 -0600 | [diff] [blame] | 42 | #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h> | 
 | 43 | #include <configstore/Utils.h> | 
 | 44 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 45 | namespace android { | 
 | 46 |  | 
| Peiyong Lin | fd997e0 | 2018-03-28 15:29:00 -0700 | [diff] [blame] | 47 | using ui::ColorMode; | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 48 | using ui::Dataspace; | 
| Peiyong Lin | fd997e0 | 2018-03-28 15:29:00 -0700 | [diff] [blame] | 49 |  | 
| Ian Elliott | a2eb34c | 2017-07-18 11:05:49 -0600 | [diff] [blame] | 50 | Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp) | 
 | 51 |       : mGraphicBufferProducer(bufferProducer), | 
 | 52 |         mCrop(Rect::EMPTY_RECT), | 
 | 53 |         mBufferAge(0), | 
 | 54 |         mGenerationNumber(0), | 
 | 55 |         mSharedBufferMode(false), | 
 | 56 |         mAutoRefresh(false), | 
 | 57 |         mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), | 
 | 58 |         mSharedBufferHasBeenQueued(false), | 
 | 59 |         mQueriedSupportedTimestamps(false), | 
 | 60 |         mFrameTimestampsSupportsPresent(false), | 
 | 61 |         mEnableFrameTimestamps(false), | 
 | 62 |         mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 63 |     // Initialize the ANativeWindow function pointers. | 
 | 64 |     ANativeWindow::setSwapInterval  = hook_setSwapInterval; | 
 | 65 |     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer; | 
 | 66 |     ANativeWindow::cancelBuffer     = hook_cancelBuffer; | 
 | 67 |     ANativeWindow::queueBuffer      = hook_queueBuffer; | 
 | 68 |     ANativeWindow::query            = hook_query; | 
 | 69 |     ANativeWindow::perform          = hook_perform; | 
 | 70 |  | 
 | 71 |     ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED; | 
 | 72 |     ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED; | 
 | 73 |     ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED; | 
 | 74 |     ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED; | 
 | 75 |  | 
 | 76 |     const_cast<int&>(ANativeWindow::minSwapInterval) = 0; | 
 | 77 |     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; | 
 | 78 |  | 
 | 79 |     mReqWidth = 0; | 
 | 80 |     mReqHeight = 0; | 
 | 81 |     mReqFormat = 0; | 
 | 82 |     mReqUsage = 0; | 
 | 83 |     mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO; | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 84 |     mDataSpace = Dataspace::UNKNOWN; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 85 |     mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; | 
 | 86 |     mTransform = 0; | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 87 |     mStickyTransform = 0; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 88 |     mDefaultWidth = 0; | 
 | 89 |     mDefaultHeight = 0; | 
 | 90 |     mUserWidth = 0; | 
 | 91 |     mUserHeight = 0; | 
 | 92 |     mTransformHint = 0; | 
 | 93 |     mConsumerRunningBehind = false; | 
 | 94 |     mConnectedToCpu = false; | 
| Eino-Ville Talvala | 7895e90 | 2013-08-21 11:53:37 -0700 | [diff] [blame] | 95 |     mProducerControlledByApp = controlledByApp; | 
| Mathias Agopian | 7cdd786 | 2013-07-18 22:10:56 -0700 | [diff] [blame] | 96 |     mSwapIntervalZero = false; | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 97 | } | 
 | 98 |  | 
| Mathias Agopian | 35ffa6a | 2013-03-12 18:45:09 -0700 | [diff] [blame] | 99 | Surface::~Surface() { | 
 | 100 |     if (mConnectedToCpu) { | 
 | 101 |         Surface::disconnect(NATIVE_WINDOW_API_CPU); | 
 | 102 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 103 | } | 
 | 104 |  | 
| Brian Anderson | 3da8d27 | 2016-07-28 16:20:47 -0700 | [diff] [blame] | 105 | sp<ISurfaceComposer> Surface::composerService() const { | 
 | 106 |     return ComposerService::getComposerService(); | 
 | 107 | } | 
 | 108 |  | 
| Brian Anderson | 0a61b0c | 2016-12-07 14:55:56 -0800 | [diff] [blame] | 109 | nsecs_t Surface::now() const { | 
 | 110 |     return systemTime(); | 
 | 111 | } | 
 | 112 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 113 | sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const { | 
 | 114 |     return mGraphicBufferProducer; | 
 | 115 | } | 
 | 116 |  | 
| Wonsik Kim | 0ee14ca | 2014-03-17 17:46:53 +0900 | [diff] [blame] | 117 | void Surface::setSidebandStream(const sp<NativeHandle>& stream) { | 
 | 118 |     mGraphicBufferProducer->setSidebandStream(stream); | 
 | 119 | } | 
 | 120 |  | 
| Dan Stoza | 29a3e90 | 2014-06-20 13:13:57 -0700 | [diff] [blame] | 121 | void Surface::allocateBuffers() { | 
 | 122 |     uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth; | 
 | 123 |     uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight; | 
| Pablo Ceballos | 567dbbb | 2015-08-26 18:59:08 -0700 | [diff] [blame] | 124 |     mGraphicBufferProducer->allocateBuffers(reqWidth, reqHeight, | 
 | 125 |             mReqFormat, mReqUsage); | 
| Dan Stoza | 29a3e90 | 2014-06-20 13:13:57 -0700 | [diff] [blame] | 126 | } | 
 | 127 |  | 
| Dan Stoza | 812ed06 | 2015-06-02 15:45:22 -0700 | [diff] [blame] | 128 | status_t Surface::setGenerationNumber(uint32_t generation) { | 
 | 129 |     status_t result = mGraphicBufferProducer->setGenerationNumber(generation); | 
 | 130 |     if (result == NO_ERROR) { | 
 | 131 |         mGenerationNumber = generation; | 
 | 132 |     } | 
 | 133 |     return result; | 
 | 134 | } | 
 | 135 |  | 
| Dan Stoza | 7dde599 | 2015-05-22 09:51:44 -0700 | [diff] [blame] | 136 | uint64_t Surface::getNextFrameNumber() const { | 
| Pablo Ceballos | bc8c192 | 2016-07-01 14:15:41 -0700 | [diff] [blame] | 137 |     Mutex::Autolock lock(mMutex); | 
 | 138 |     return mNextFrameNumber; | 
| Dan Stoza | 7dde599 | 2015-05-22 09:51:44 -0700 | [diff] [blame] | 139 | } | 
 | 140 |  | 
| Dan Stoza | c6f30bd | 2015-06-08 09:32:50 -0700 | [diff] [blame] | 141 | String8 Surface::getConsumerName() const { | 
 | 142 |     return mGraphicBufferProducer->getConsumerName(); | 
 | 143 | } | 
 | 144 |  | 
| Dan Stoza | 127fc63 | 2015-06-30 13:43:32 -0700 | [diff] [blame] | 145 | status_t Surface::setDequeueTimeout(nsecs_t timeout) { | 
 | 146 |     return mGraphicBufferProducer->setDequeueTimeout(timeout); | 
 | 147 | } | 
 | 148 |  | 
| Dan Stoza | 50101d0 | 2016-04-07 16:53:23 -0700 | [diff] [blame] | 149 | status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, | 
| John Reck | 1a61da5 | 2016-04-28 13:18:15 -0700 | [diff] [blame] | 150 |         sp<Fence>* outFence, float outTransformMatrix[16]) { | 
 | 151 |     return mGraphicBufferProducer->getLastQueuedBuffer(outBuffer, outFence, | 
 | 152 |             outTransformMatrix); | 
| Dan Stoza | 50101d0 | 2016-04-07 16:53:23 -0700 | [diff] [blame] | 153 | } | 
 | 154 |  | 
| Brian Anderson | 0a61b0c | 2016-12-07 14:55:56 -0800 | [diff] [blame] | 155 | status_t Surface::getDisplayRefreshCycleDuration(nsecs_t* outRefreshDuration) { | 
 | 156 |     ATRACE_CALL(); | 
 | 157 |  | 
 | 158 |     DisplayStatInfo stats; | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 159 |     status_t result = composerService()->getDisplayStats(nullptr, &stats); | 
| Chih-Hung Hsieh | d66be0a | 2017-10-05 13:51:32 -0700 | [diff] [blame] | 160 |     if (result != NO_ERROR) { | 
 | 161 |         return result; | 
 | 162 |     } | 
| Brian Anderson | 0a61b0c | 2016-12-07 14:55:56 -0800 | [diff] [blame] | 163 |  | 
 | 164 |     *outRefreshDuration = stats.vsyncPeriod; | 
 | 165 |  | 
 | 166 |     return NO_ERROR; | 
 | 167 | } | 
 | 168 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 169 | void Surface::enableFrameTimestamps(bool enable) { | 
 | 170 |     Mutex::Autolock lock(mMutex); | 
| Brian Anderson | 0a61b0c | 2016-12-07 14:55:56 -0800 | [diff] [blame] | 171 |     // If going from disabled to enabled, get the initial values for | 
 | 172 |     // compositor and display timing. | 
 | 173 |     if (!mEnableFrameTimestamps && enable) { | 
 | 174 |         FrameEventHistoryDelta delta; | 
 | 175 |         mGraphicBufferProducer->getFrameTimestamps(&delta); | 
 | 176 |         mFrameEventHistory->applyDelta(delta); | 
 | 177 |     } | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 178 |     mEnableFrameTimestamps = enable; | 
 | 179 | } | 
 | 180 |  | 
| Brian Anderson | 0a61b0c | 2016-12-07 14:55:56 -0800 | [diff] [blame] | 181 | status_t Surface::getCompositorTiming( | 
 | 182 |         nsecs_t* compositeDeadline, nsecs_t* compositeInterval, | 
 | 183 |         nsecs_t* compositeToPresentLatency) { | 
 | 184 |     Mutex::Autolock lock(mMutex); | 
 | 185 |     if (!mEnableFrameTimestamps) { | 
 | 186 |         return INVALID_OPERATION; | 
 | 187 |     } | 
 | 188 |  | 
 | 189 |     if (compositeDeadline != nullptr) { | 
 | 190 |         *compositeDeadline = | 
 | 191 |                 mFrameEventHistory->getNextCompositeDeadline(now()); | 
 | 192 |     } | 
 | 193 |     if (compositeInterval != nullptr) { | 
 | 194 |         *compositeInterval = mFrameEventHistory->getCompositeInterval(); | 
 | 195 |     } | 
 | 196 |     if (compositeToPresentLatency != nullptr) { | 
 | 197 |         *compositeToPresentLatency = | 
 | 198 |                 mFrameEventHistory->getCompositeToPresentLatency(); | 
 | 199 |     } | 
 | 200 |     return NO_ERROR; | 
 | 201 | } | 
 | 202 |  | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 203 | static bool checkConsumerForUpdates( | 
 | 204 |         const FrameEvents* e, const uint64_t lastFrameNumber, | 
| Brian Anderson | f7fd56a | 2016-09-02 10:10:04 -0700 | [diff] [blame] | 205 |         const nsecs_t* outLatchTime, | 
 | 206 |         const nsecs_t* outFirstRefreshStartTime, | 
 | 207 |         const nsecs_t* outLastRefreshStartTime, | 
| Brian Anderson | b04c6f0 | 2016-10-21 12:57:46 -0700 | [diff] [blame] | 208 |         const nsecs_t* outGpuCompositionDoneTime, | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 209 |         const nsecs_t* outDisplayPresentTime, | 
| Brian Anderson | f7fd56a | 2016-09-02 10:10:04 -0700 | [diff] [blame] | 210 |         const nsecs_t* outDequeueReadyTime, | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 211 |         const nsecs_t* outReleaseTime) { | 
| Brian Anderson | f7fd56a | 2016-09-02 10:10:04 -0700 | [diff] [blame] | 212 |     bool checkForLatch = (outLatchTime != nullptr) && !e->hasLatchInfo(); | 
 | 213 |     bool checkForFirstRefreshStart = (outFirstRefreshStartTime != nullptr) && | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 214 |             !e->hasFirstRefreshStartInfo(); | 
| Brian Anderson | b04c6f0 | 2016-10-21 12:57:46 -0700 | [diff] [blame] | 215 |     bool checkForGpuCompositionDone = (outGpuCompositionDoneTime != nullptr) && | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 216 |             !e->hasGpuCompositionDoneInfo(); | 
 | 217 |     bool checkForDisplayPresent = (outDisplayPresentTime != nullptr) && | 
 | 218 |             !e->hasDisplayPresentInfo(); | 
 | 219 |  | 
| Brian Anderson | 6b37671 | 2017-04-04 10:51:39 -0700 | [diff] [blame] | 220 |     // LastRefreshStart, DequeueReady, and Release are never available for the | 
 | 221 |     // last frame. | 
| Brian Anderson | f7fd56a | 2016-09-02 10:10:04 -0700 | [diff] [blame] | 222 |     bool checkForLastRefreshStart = (outLastRefreshStartTime != nullptr) && | 
 | 223 |             !e->hasLastRefreshStartInfo() && | 
 | 224 |             (e->frameNumber != lastFrameNumber); | 
| Brian Anderson | f7fd56a | 2016-09-02 10:10:04 -0700 | [diff] [blame] | 225 |     bool checkForDequeueReady = (outDequeueReadyTime != nullptr) && | 
 | 226 |             !e->hasDequeueReadyInfo() && (e->frameNumber != lastFrameNumber); | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 227 |     bool checkForRelease = (outReleaseTime != nullptr) && | 
 | 228 |             !e->hasReleaseInfo() && (e->frameNumber != lastFrameNumber); | 
 | 229 |  | 
 | 230 |     // RequestedPresent and Acquire info are always available producer-side. | 
| Brian Anderson | f7fd56a | 2016-09-02 10:10:04 -0700 | [diff] [blame] | 231 |     return checkForLatch || checkForFirstRefreshStart || | 
| Brian Anderson | b04c6f0 | 2016-10-21 12:57:46 -0700 | [diff] [blame] | 232 |             checkForLastRefreshStart || checkForGpuCompositionDone || | 
| Brian Anderson | 4e606e3 | 2017-03-16 15:34:57 -0700 | [diff] [blame] | 233 |             checkForDisplayPresent || checkForDequeueReady || checkForRelease; | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 234 | } | 
 | 235 |  | 
| Brian Anderson | 3d4039d | 2016-09-23 16:31:30 -0700 | [diff] [blame] | 236 | static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) { | 
 | 237 |     if (dst != nullptr) { | 
| Brian Anderson | dc96fdf | 2017-03-20 16:54:25 -0700 | [diff] [blame] | 238 |         // We always get valid timestamps for these eventually. | 
 | 239 |         *dst = (src == FrameEvents::TIMESTAMP_PENDING) ? | 
 | 240 |                 NATIVE_WINDOW_TIMESTAMP_PENDING : src; | 
| Brian Anderson | 3d4039d | 2016-09-23 16:31:30 -0700 | [diff] [blame] | 241 |     } | 
 | 242 | } | 
 | 243 |  | 
| Brian Anderson | dc96fdf | 2017-03-20 16:54:25 -0700 | [diff] [blame] | 244 | static void getFrameTimestampFence(nsecs_t *dst, | 
 | 245 |         const std::shared_ptr<FenceTime>& src, bool fenceShouldBeKnown) { | 
| Brian Anderson | 3d4039d | 2016-09-23 16:31:30 -0700 | [diff] [blame] | 246 |     if (dst != nullptr) { | 
| Brian Anderson | dc96fdf | 2017-03-20 16:54:25 -0700 | [diff] [blame] | 247 |         if (!fenceShouldBeKnown) { | 
 | 248 |             *dst = NATIVE_WINDOW_TIMESTAMP_PENDING; | 
 | 249 |             return; | 
 | 250 |         } | 
 | 251 |  | 
| Brian Anderson | 3d4039d | 2016-09-23 16:31:30 -0700 | [diff] [blame] | 252 |         nsecs_t signalTime = src->getSignalTime(); | 
| Brian Anderson | dc96fdf | 2017-03-20 16:54:25 -0700 | [diff] [blame] | 253 |         *dst = (signalTime == Fence::SIGNAL_TIME_PENDING) ? | 
 | 254 |                     NATIVE_WINDOW_TIMESTAMP_PENDING : | 
 | 255 |                 (signalTime == Fence::SIGNAL_TIME_INVALID) ? | 
 | 256 |                     NATIVE_WINDOW_TIMESTAMP_INVALID : | 
 | 257 |                 signalTime; | 
| Brian Anderson | 3d4039d | 2016-09-23 16:31:30 -0700 | [diff] [blame] | 258 |     } | 
 | 259 | } | 
 | 260 |  | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 261 | status_t Surface::getFrameTimestamps(uint64_t frameNumber, | 
| Brian Anderson | dbd0ea8 | 2016-07-22 09:38:59 -0700 | [diff] [blame] | 262 |         nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime, | 
| Brian Anderson | f7fd56a | 2016-09-02 10:10:04 -0700 | [diff] [blame] | 263 |         nsecs_t* outLatchTime, nsecs_t* outFirstRefreshStartTime, | 
| Brian Anderson | b04c6f0 | 2016-10-21 12:57:46 -0700 | [diff] [blame] | 264 |         nsecs_t* outLastRefreshStartTime, nsecs_t* outGpuCompositionDoneTime, | 
| Brian Anderson | 4e606e3 | 2017-03-16 15:34:57 -0700 | [diff] [blame] | 265 |         nsecs_t* outDisplayPresentTime, nsecs_t* outDequeueReadyTime, | 
 | 266 |         nsecs_t* outReleaseTime) { | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 267 |     ATRACE_CALL(); | 
 | 268 |  | 
| Brian Anderson | 3890c39 | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 269 |     Mutex::Autolock lock(mMutex); | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 270 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 271 |     if (!mEnableFrameTimestamps) { | 
 | 272 |         return INVALID_OPERATION; | 
 | 273 |     } | 
 | 274 |  | 
| Brian Anderson | 6b37671 | 2017-04-04 10:51:39 -0700 | [diff] [blame] | 275 |     // Verify the requested timestamps are supported. | 
 | 276 |     querySupportedTimestampsLocked(); | 
 | 277 |     if (outDisplayPresentTime != nullptr && !mFrameTimestampsSupportsPresent) { | 
 | 278 |         return BAD_VALUE; | 
 | 279 |     } | 
 | 280 |  | 
| Brian Anderson | 3da8d27 | 2016-07-28 16:20:47 -0700 | [diff] [blame] | 281 |     FrameEvents* events = mFrameEventHistory->getFrame(frameNumber); | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 282 |     if (events == nullptr) { | 
 | 283 |         // If the entry isn't available in the producer, it's definitely not | 
 | 284 |         // available in the consumer. | 
 | 285 |         return NAME_NOT_FOUND; | 
| Brian Anderson | 3890c39 | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 286 |     } | 
 | 287 |  | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 288 |     // Update our cache of events if the requested events are not available. | 
 | 289 |     if (checkConsumerForUpdates(events, mLastFrameNumber, | 
| Brian Anderson | f7fd56a | 2016-09-02 10:10:04 -0700 | [diff] [blame] | 290 |             outLatchTime, outFirstRefreshStartTime, outLastRefreshStartTime, | 
| Brian Anderson | b04c6f0 | 2016-10-21 12:57:46 -0700 | [diff] [blame] | 291 |             outGpuCompositionDoneTime, outDisplayPresentTime, | 
| Brian Anderson | 4e606e3 | 2017-03-16 15:34:57 -0700 | [diff] [blame] | 292 |             outDequeueReadyTime, outReleaseTime)) { | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 293 |         FrameEventHistoryDelta delta; | 
 | 294 |         mGraphicBufferProducer->getFrameTimestamps(&delta); | 
| Brian Anderson | 3da8d27 | 2016-07-28 16:20:47 -0700 | [diff] [blame] | 295 |         mFrameEventHistory->applyDelta(delta); | 
 | 296 |         events = mFrameEventHistory->getFrame(frameNumber); | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 297 |     } | 
 | 298 |  | 
| Brian Anderson | 3890c39 | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 299 |     if (events == nullptr) { | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 300 |         // The entry was available before the update, but was overwritten | 
 | 301 |         // after the update. Make sure not to send the wrong frame's data. | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 302 |         return NAME_NOT_FOUND; | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 303 |     } | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 304 |  | 
| Brian Anderson | 3d4039d | 2016-09-23 16:31:30 -0700 | [diff] [blame] | 305 |     getFrameTimestamp(outRequestedPresentTime, events->requestedPresentTime); | 
| Brian Anderson | f7fd56a | 2016-09-02 10:10:04 -0700 | [diff] [blame] | 306 |     getFrameTimestamp(outLatchTime, events->latchTime); | 
 | 307 |     getFrameTimestamp(outFirstRefreshStartTime, events->firstRefreshStartTime); | 
 | 308 |     getFrameTimestamp(outLastRefreshStartTime, events->lastRefreshStartTime); | 
 | 309 |     getFrameTimestamp(outDequeueReadyTime, events->dequeueReadyTime); | 
| Brian Anderson | 3890c39 | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 310 |  | 
| Brian Anderson | dc96fdf | 2017-03-20 16:54:25 -0700 | [diff] [blame] | 311 |     getFrameTimestampFence(outAcquireTime, events->acquireFence, | 
 | 312 |             events->hasAcquireInfo()); | 
 | 313 |     getFrameTimestampFence(outGpuCompositionDoneTime, | 
 | 314 |             events->gpuCompositionDoneFence, | 
 | 315 |             events->hasGpuCompositionDoneInfo()); | 
 | 316 |     getFrameTimestampFence(outDisplayPresentTime, events->displayPresentFence, | 
 | 317 |             events->hasDisplayPresentInfo()); | 
 | 318 |     getFrameTimestampFence(outReleaseTime, events->releaseFence, | 
 | 319 |             events->hasReleaseInfo()); | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 320 |  | 
 | 321 |     return NO_ERROR; | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 322 | } | 
 | 323 |  | 
| Courtney Goeltzenleuchter | a0c93e1 | 2017-03-17 16:16:48 -0600 | [diff] [blame] | 324 | using namespace android::hardware::configstore; | 
 | 325 | using namespace android::hardware::configstore::V1_0; | 
 | 326 |  | 
| Courtney Goeltzenleuchter | 1eb1b27 | 2017-02-02 16:51:06 -0700 | [diff] [blame] | 327 | status_t Surface::getWideColorSupport(bool* supported) { | 
 | 328 |     ATRACE_CALL(); | 
 | 329 |  | 
 | 330 |     sp<IBinder> display( | 
 | 331 |         composerService()->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); | 
| Peiyong Lin | a52f029 | 2018-03-14 17:26:31 -0700 | [diff] [blame] | 332 |     Vector<ColorMode> colorModes; | 
| Courtney Goeltzenleuchter | 1eb1b27 | 2017-02-02 16:51:06 -0700 | [diff] [blame] | 333 |     status_t err = | 
 | 334 |         composerService()->getDisplayColorModes(display, &colorModes); | 
 | 335 |  | 
 | 336 |     if (err) | 
 | 337 |         return err; | 
 | 338 |  | 
| Courtney Goeltzenleuchter | a0c93e1 | 2017-03-17 16:16:48 -0600 | [diff] [blame] | 339 |     bool wideColorBoardConfig = | 
 | 340 |         getBool<ISurfaceFlingerConfigs, | 
 | 341 |                 &ISurfaceFlingerConfigs::hasWideColorDisplay>(false); | 
 | 342 |  | 
| Courtney Goeltzenleuchter | 1eb1b27 | 2017-02-02 16:51:06 -0700 | [diff] [blame] | 343 |     *supported = false; | 
| Peiyong Lin | a52f029 | 2018-03-14 17:26:31 -0700 | [diff] [blame] | 344 |     for (ColorMode colorMode : colorModes) { | 
| Courtney Goeltzenleuchter | 1eb1b27 | 2017-02-02 16:51:06 -0700 | [diff] [blame] | 345 |         switch (colorMode) { | 
| Peiyong Lin | a52f029 | 2018-03-14 17:26:31 -0700 | [diff] [blame] | 346 |             case ColorMode::DISPLAY_P3: | 
 | 347 |             case ColorMode::ADOBE_RGB: | 
 | 348 |             case ColorMode::DCI_P3: | 
| Courtney Goeltzenleuchter | a0c93e1 | 2017-03-17 16:16:48 -0600 | [diff] [blame] | 349 |                 if (wideColorBoardConfig) { | 
 | 350 |                     *supported = true; | 
 | 351 |                 } | 
| Courtney Goeltzenleuchter | 1eb1b27 | 2017-02-02 16:51:06 -0700 | [diff] [blame] | 352 |                 break; | 
 | 353 |             default: | 
 | 354 |                 break; | 
 | 355 |         } | 
 | 356 |     } | 
 | 357 |  | 
 | 358 |     return NO_ERROR; | 
 | 359 | } | 
 | 360 |  | 
| Courtney Goeltzenleuchter | c5b97c5 | 2017-02-26 14:47:13 -0700 | [diff] [blame] | 361 | status_t Surface::getHdrSupport(bool* supported) { | 
 | 362 |     ATRACE_CALL(); | 
 | 363 |  | 
 | 364 |     sp<IBinder> display( | 
 | 365 |         composerService()->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); | 
 | 366 |     HdrCapabilities hdrCapabilities; | 
 | 367 |     status_t err = | 
 | 368 |         composerService()->getHdrCapabilities(display, &hdrCapabilities); | 
 | 369 |  | 
 | 370 |     if (err) | 
 | 371 |         return err; | 
 | 372 |  | 
 | 373 |     *supported = !hdrCapabilities.getSupportedHdrTypes().empty(); | 
 | 374 |  | 
 | 375 |     return NO_ERROR; | 
 | 376 | } | 
 | 377 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 378 | int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) { | 
 | 379 |     Surface* c = getSelf(window); | 
 | 380 |     return c->setSwapInterval(interval); | 
 | 381 | } | 
 | 382 |  | 
 | 383 | int Surface::hook_dequeueBuffer(ANativeWindow* window, | 
 | 384 |         ANativeWindowBuffer** buffer, int* fenceFd) { | 
 | 385 |     Surface* c = getSelf(window); | 
 | 386 |     return c->dequeueBuffer(buffer, fenceFd); | 
 | 387 | } | 
 | 388 |  | 
 | 389 | int Surface::hook_cancelBuffer(ANativeWindow* window, | 
 | 390 |         ANativeWindowBuffer* buffer, int fenceFd) { | 
 | 391 |     Surface* c = getSelf(window); | 
 | 392 |     return c->cancelBuffer(buffer, fenceFd); | 
 | 393 | } | 
 | 394 |  | 
 | 395 | int Surface::hook_queueBuffer(ANativeWindow* window, | 
 | 396 |         ANativeWindowBuffer* buffer, int fenceFd) { | 
 | 397 |     Surface* c = getSelf(window); | 
 | 398 |     return c->queueBuffer(buffer, fenceFd); | 
 | 399 | } | 
 | 400 |  | 
 | 401 | int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, | 
 | 402 |         ANativeWindowBuffer** buffer) { | 
 | 403 |     Surface* c = getSelf(window); | 
 | 404 |     ANativeWindowBuffer* buf; | 
 | 405 |     int fenceFd = -1; | 
 | 406 |     int result = c->dequeueBuffer(&buf, &fenceFd); | 
| Mike Stroyan | 87709c9 | 2016-06-03 12:43:26 -0600 | [diff] [blame] | 407 |     if (result != OK) { | 
 | 408 |         return result; | 
 | 409 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 410 |     sp<Fence> fence(new Fence(fenceFd)); | 
| Mathias Agopian | ea74d3b | 2013-05-16 18:03:22 -0700 | [diff] [blame] | 411 |     int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED"); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 412 |     if (waitResult != OK) { | 
 | 413 |         ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d", | 
 | 414 |                 waitResult); | 
 | 415 |         c->cancelBuffer(buf, -1); | 
 | 416 |         return waitResult; | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 417 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 418 |     *buffer = buf; | 
 | 419 |     return result; | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 420 | } | 
 | 421 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 422 | int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window, | 
 | 423 |         ANativeWindowBuffer* buffer) { | 
 | 424 |     Surface* c = getSelf(window); | 
 | 425 |     return c->cancelBuffer(buffer, -1); | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 426 | } | 
 | 427 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 428 | int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window, | 
 | 429 |         ANativeWindowBuffer* buffer) { | 
 | 430 |     Surface* c = getSelf(window); | 
 | 431 |     return c->lockBuffer_DEPRECATED(buffer); | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 432 | } | 
 | 433 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 434 | int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window, | 
 | 435 |         ANativeWindowBuffer* buffer) { | 
 | 436 |     Surface* c = getSelf(window); | 
 | 437 |     return c->queueBuffer(buffer, -1); | 
| Jamie Gennis | f15a83f | 2012-05-10 20:43:55 -0700 | [diff] [blame] | 438 | } | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 439 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 440 | int Surface::hook_query(const ANativeWindow* window, | 
 | 441 |                                 int what, int* value) { | 
 | 442 |     const Surface* c = getSelf(window); | 
 | 443 |     return c->query(what, value); | 
 | 444 | } | 
 | 445 |  | 
 | 446 | int Surface::hook_perform(ANativeWindow* window, int operation, ...) { | 
 | 447 |     va_list args; | 
 | 448 |     va_start(args, operation); | 
 | 449 |     Surface* c = getSelf(window); | 
| Haixia Shi | d89c2bb | 2015-09-14 11:02:18 -0700 | [diff] [blame] | 450 |     int result = c->perform(operation, args); | 
 | 451 |     va_end(args); | 
 | 452 |     return result; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 453 | } | 
 | 454 |  | 
 | 455 | int Surface::setSwapInterval(int interval) { | 
 | 456 |     ATRACE_CALL(); | 
 | 457 |     // EGL specification states: | 
 | 458 |     //  interval is silently clamped to minimum and maximum implementation | 
 | 459 |     //  dependent values before being stored. | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 460 |  | 
 | 461 |     if (interval < minSwapInterval) | 
 | 462 |         interval = minSwapInterval; | 
 | 463 |  | 
 | 464 |     if (interval > maxSwapInterval) | 
 | 465 |         interval = maxSwapInterval; | 
 | 466 |  | 
| Jorim Jaggi | 0a3e784 | 2018-07-17 13:48:33 +0200 | [diff] [blame] | 467 |     const bool wasSwapIntervalZero = mSwapIntervalZero; | 
| Mathias Agopian | 7cdd786 | 2013-07-18 22:10:56 -0700 | [diff] [blame] | 468 |     mSwapIntervalZero = (interval == 0); | 
| Jorim Jaggi | 0a3e784 | 2018-07-17 13:48:33 +0200 | [diff] [blame] | 469 |  | 
 | 470 |     if (mSwapIntervalZero != wasSwapIntervalZero) { | 
 | 471 |         mGraphicBufferProducer->setAsyncMode(mSwapIntervalZero); | 
 | 472 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 473 |  | 
| Mathias Agopian | 7cdd786 | 2013-07-18 22:10:56 -0700 | [diff] [blame] | 474 |     return NO_ERROR; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 475 | } | 
 | 476 |  | 
| Mathias Agopian | ba93b3f | 2013-08-01 15:48:40 -0700 | [diff] [blame] | 477 | int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 478 |     ATRACE_CALL(); | 
 | 479 |     ALOGV("Surface::dequeueBuffer"); | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 480 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 481 |     uint32_t reqWidth; | 
 | 482 |     uint32_t reqHeight; | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 483 |     PixelFormat reqFormat; | 
| Mathias Agopian | cb496ac | 2017-05-22 14:21:00 -0700 | [diff] [blame] | 484 |     uint64_t reqUsage; | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 485 |     bool enableFrameTimestamps; | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 486 |  | 
 | 487 |     { | 
 | 488 |         Mutex::Autolock lock(mMutex); | 
| Yin-Chia Yeh | 1f2af5c | 2017-05-11 16:54:04 -0700 | [diff] [blame] | 489 |         if (mReportRemovedBuffers) { | 
 | 490 |             mRemovedBuffers.clear(); | 
 | 491 |         } | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 492 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 493 |         reqWidth = mReqWidth ? mReqWidth : mUserWidth; | 
 | 494 |         reqHeight = mReqHeight ? mReqHeight : mUserHeight; | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 495 |  | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 496 |         reqFormat = mReqFormat; | 
 | 497 |         reqUsage = mReqUsage; | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 498 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 499 |         enableFrameTimestamps = mEnableFrameTimestamps; | 
 | 500 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 501 |         if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot != | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 502 |                 BufferItem::INVALID_BUFFER_SLOT) { | 
 | 503 |             sp<GraphicBuffer>& gbuf(mSlots[mSharedBufferSlot].buffer); | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 504 |             if (gbuf != nullptr) { | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 505 |                 *buffer = gbuf.get(); | 
 | 506 |                 *fenceFd = -1; | 
 | 507 |                 return OK; | 
 | 508 |             } | 
 | 509 |         } | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 510 |     } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer | 
 | 511 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 512 |     int buf = -1; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 513 |     sp<Fence> fence; | 
| Dan Stoza | 932f008 | 2017-05-31 13:50:16 -0700 | [diff] [blame] | 514 |     nsecs_t startTime = systemTime(); | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 515 |  | 
 | 516 |     FrameEventHistoryDelta frameTimestamps; | 
| Ian Elliott | a2eb34c | 2017-07-18 11:05:49 -0600 | [diff] [blame] | 517 |     status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight, | 
 | 518 |                                                             reqFormat, reqUsage, &mBufferAge, | 
 | 519 |                                                             enableFrameTimestamps ? &frameTimestamps | 
 | 520 |                                                                                   : nullptr); | 
| Dan Stoza | 932f008 | 2017-05-31 13:50:16 -0700 | [diff] [blame] | 521 |     mLastDequeueDuration = systemTime() - startTime; | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 522 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 523 |     if (result < 0) { | 
| Pablo Ceballos | 567dbbb | 2015-08-26 18:59:08 -0700 | [diff] [blame] | 524 |         ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer" | 
| Mathias Agopian | cb496ac | 2017-05-22 14:21:00 -0700 | [diff] [blame] | 525 |                 "(%d, %d, %d, %#" PRIx64 ") failed: %d", | 
 | 526 |                 reqWidth, reqHeight, reqFormat, reqUsage, result); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 527 |         return result; | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 528 |     } | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 529 |  | 
| Dan Stoza | 90ce2a9 | 2017-05-01 16:31:53 -0700 | [diff] [blame] | 530 |     if (buf < 0 || buf >= NUM_BUFFER_SLOTS) { | 
 | 531 |         ALOGE("dequeueBuffer: IGraphicBufferProducer returned invalid slot number %d", buf); | 
 | 532 |         android_errorWriteLog(0x534e4554, "36991414"); // SafetyNet logging | 
 | 533 |         return FAILED_TRANSACTION; | 
 | 534 |     } | 
 | 535 |  | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 536 |     Mutex::Autolock lock(mMutex); | 
 | 537 |  | 
| Dan Stoza | 932f008 | 2017-05-31 13:50:16 -0700 | [diff] [blame] | 538 |     // Write this while holding the mutex | 
 | 539 |     mLastDequeueStartTime = startTime; | 
 | 540 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 541 |     sp<GraphicBuffer>& gbuf(mSlots[buf].buffer); | 
| Mathias Agopian | ba93b3f | 2013-08-01 15:48:40 -0700 | [diff] [blame] | 542 |  | 
 | 543 |     // this should never happen | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 544 |     ALOGE_IF(fence == nullptr, "Surface::dequeueBuffer: received null Fence! buf=%d", buf); | 
| Mathias Agopian | ba93b3f | 2013-08-01 15:48:40 -0700 | [diff] [blame] | 545 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 546 |     if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) { | 
 | 547 |         freeAllBuffers(); | 
| Mathias Agopian | 579b3f8 | 2010-06-08 19:54:15 -0700 | [diff] [blame] | 548 |     } | 
| Ted Bonkenburg | bd050ab | 2011-07-15 15:10:10 -0700 | [diff] [blame] | 549 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 550 |     if (enableFrameTimestamps) { | 
| Brian Anderson | 3da8d27 | 2016-07-28 16:20:47 -0700 | [diff] [blame] | 551 |          mFrameEventHistory->applyDelta(frameTimestamps); | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 552 |     } | 
 | 553 |  | 
| Yin-Chia Yeh | e572fd7 | 2017-03-28 19:07:39 -0700 | [diff] [blame] | 554 |     if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) { | 
 | 555 |         if (mReportRemovedBuffers && (gbuf != nullptr)) { | 
| Yin-Chia Yeh | e572fd7 | 2017-03-28 19:07:39 -0700 | [diff] [blame] | 556 |             mRemovedBuffers.push_back(gbuf); | 
 | 557 |         } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 558 |         result = mGraphicBufferProducer->requestBuffer(buf, &gbuf); | 
 | 559 |         if (result != NO_ERROR) { | 
| Mathias Agopian | ba93b3f | 2013-08-01 15:48:40 -0700 | [diff] [blame] | 560 |             ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result); | 
| Jesse Hall | 9f5a1b6 | 2014-10-02 11:09:03 -0700 | [diff] [blame] | 561 |             mGraphicBufferProducer->cancelBuffer(buf, fence); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 562 |             return result; | 
 | 563 |         } | 
 | 564 |     } | 
| Mathias Agopian | 579b3f8 | 2010-06-08 19:54:15 -0700 | [diff] [blame] | 565 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 566 |     if (fence->isValid()) { | 
 | 567 |         *fenceFd = fence->dup(); | 
 | 568 |         if (*fenceFd == -1) { | 
 | 569 |             ALOGE("dequeueBuffer: error duping fence: %d", errno); | 
 | 570 |             // dup() should never fail; something is badly wrong. Soldier on | 
 | 571 |             // and hope for the best; the worst that should happen is some | 
 | 572 |             // visible corruption that lasts until the next frame. | 
 | 573 |         } | 
| Ted Bonkenburg | e5d6eb8 | 2011-08-09 22:38:41 -0700 | [diff] [blame] | 574 |     } else { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 575 |         *fenceFd = -1; | 
| Mathias Agopian | a0c30e9 | 2010-06-04 18:26:32 -0700 | [diff] [blame] | 576 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 577 |  | 
 | 578 |     *buffer = gbuf.get(); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 579 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 580 |     if (mSharedBufferMode && mAutoRefresh) { | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 581 |         mSharedBufferSlot = buf; | 
 | 582 |         mSharedBufferHasBeenQueued = false; | 
 | 583 |     } else if (mSharedBufferSlot == buf) { | 
 | 584 |         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; | 
 | 585 |         mSharedBufferHasBeenQueued = false; | 
 | 586 |     } | 
 | 587 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 588 |     return OK; | 
| Jamie Gennis | aca4e22 | 2010-07-15 17:29:15 -0700 | [diff] [blame] | 589 | } | 
 | 590 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 591 | int Surface::cancelBuffer(android_native_buffer_t* buffer, | 
 | 592 |         int fenceFd) { | 
 | 593 |     ATRACE_CALL(); | 
 | 594 |     ALOGV("Surface::cancelBuffer"); | 
 | 595 |     Mutex::Autolock lock(mMutex); | 
 | 596 |     int i = getSlotFromBufferLocked(buffer); | 
 | 597 |     if (i < 0) { | 
| Taiju Tsuiki | 4d0cd3f | 2015-04-30 22:15:33 +0900 | [diff] [blame] | 598 |         if (fenceFd >= 0) { | 
 | 599 |             close(fenceFd); | 
 | 600 |         } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 601 |         return i; | 
 | 602 |     } | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 603 |     if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) { | 
 | 604 |         if (fenceFd >= 0) { | 
 | 605 |             close(fenceFd); | 
 | 606 |         } | 
 | 607 |         return OK; | 
 | 608 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 609 |     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); | 
 | 610 |     mGraphicBufferProducer->cancelBuffer(i, fence); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 611 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 612 |     if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) { | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 613 |         mSharedBufferHasBeenQueued = true; | 
 | 614 |     } | 
 | 615 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 616 |     return OK; | 
 | 617 | } | 
 | 618 |  | 
 | 619 | int Surface::getSlotFromBufferLocked( | 
 | 620 |         android_native_buffer_t* buffer) const { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 621 |     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 622 |         if (mSlots[i].buffer != nullptr && | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 623 |                 mSlots[i].buffer->handle == buffer->handle) { | 
 | 624 |             return i; | 
| Jamie Gennis | aca4e22 | 2010-07-15 17:29:15 -0700 | [diff] [blame] | 625 |         } | 
 | 626 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 627 |     ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle); | 
 | 628 |     return BAD_VALUE; | 
| Mathias Agopian | a0c30e9 | 2010-06-04 18:26:32 -0700 | [diff] [blame] | 629 | } | 
 | 630 |  | 
| Igor Murashkin | 7d2d160 | 2013-11-12 18:02:20 -0800 | [diff] [blame] | 631 | int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 632 |     ALOGV("Surface::lockBuffer"); | 
 | 633 |     Mutex::Autolock lock(mMutex); | 
 | 634 |     return OK; | 
 | 635 | } | 
| Mathias Agopian | 631f358 | 2010-05-25 17:51:34 -0700 | [diff] [blame] | 636 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 637 | int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { | 
 | 638 |     ATRACE_CALL(); | 
 | 639 |     ALOGV("Surface::queueBuffer"); | 
 | 640 |     Mutex::Autolock lock(mMutex); | 
 | 641 |     int64_t timestamp; | 
| Andy McFadden | 3c25621 | 2013-08-16 14:55:39 -0700 | [diff] [blame] | 642 |     bool isAutoTimestamp = false; | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 643 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 644 |     if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) { | 
| Andy McFadden | 4b49e08 | 2013-08-02 15:31:45 -0700 | [diff] [blame] | 645 |         timestamp = systemTime(SYSTEM_TIME_MONOTONIC); | 
| Andy McFadden | 3c25621 | 2013-08-16 14:55:39 -0700 | [diff] [blame] | 646 |         isAutoTimestamp = true; | 
| Andy McFadden | 4b49e08 | 2013-08-02 15:31:45 -0700 | [diff] [blame] | 647 |         ALOGV("Surface::queueBuffer making up timestamp: %.2f ms", | 
| Colin Cross | 9a80d50 | 2016-09-27 14:12:48 -0700 | [diff] [blame] | 648 |             timestamp / 1000000.0); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 649 |     } else { | 
 | 650 |         timestamp = mTimestamp; | 
| Mathias Agopian | 631f358 | 2010-05-25 17:51:34 -0700 | [diff] [blame] | 651 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 652 |     int i = getSlotFromBufferLocked(buffer); | 
 | 653 |     if (i < 0) { | 
| Taiju Tsuiki | 4d0cd3f | 2015-04-30 22:15:33 +0900 | [diff] [blame] | 654 |         if (fenceFd >= 0) { | 
 | 655 |             close(fenceFd); | 
 | 656 |         } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 657 |         return i; | 
 | 658 |     } | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 659 |     if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) { | 
 | 660 |         if (fenceFd >= 0) { | 
 | 661 |             close(fenceFd); | 
 | 662 |         } | 
 | 663 |         return OK; | 
 | 664 |     } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 665 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 666 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 667 |     // Make sure the crop rectangle is entirely inside the buffer. | 
| Pablo Ceballos | 60d6922 | 2015-08-07 14:47:20 -0700 | [diff] [blame] | 668 |     Rect crop(Rect::EMPTY_RECT); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 669 |     mCrop.intersect(Rect(buffer->width, buffer->height), &crop); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 670 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 671 |     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); | 
 | 672 |     IGraphicBufferProducer::QueueBufferOutput output; | 
| Andy McFadden | 3c25621 | 2013-08-16 14:55:39 -0700 | [diff] [blame] | 673 |     IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp, | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 674 |             static_cast<android_dataspace>(mDataSpace), crop, mScalingMode, | 
 | 675 |             mTransform ^ mStickyTransform, fence, mStickyTransform, | 
 | 676 |             mEnableFrameTimestamps); | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 677 |  | 
| Courtney Goeltzenleuchter | 9bad0d7 | 2017-12-19 12:34:34 -0700 | [diff] [blame] | 678 |     // we should send HDR metadata as needed if this becomes a bottleneck | 
 | 679 |     input.setHdrMetadata(mHdrMetadata); | 
 | 680 |  | 
| Dan Stoza | c62acbd | 2015-04-21 16:42:49 -0700 | [diff] [blame] | 681 |     if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) { | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 682 |         input.setSurfaceDamage(Region::INVALID_REGION); | 
 | 683 |     } else { | 
| Dan Stoza | db4850c | 2015-06-25 16:10:18 -0700 | [diff] [blame] | 684 |         // Here we do two things: | 
 | 685 |         // 1) The surface damage was specified using the OpenGL ES convention of | 
 | 686 |         //    the origin being in the bottom-left corner. Here we flip to the | 
 | 687 |         //    convention that the rest of the system uses (top-left corner) by | 
 | 688 |         //    subtracting all top/bottom coordinates from the buffer height. | 
 | 689 |         // 2) If the buffer is coming in rotated (for example, because the EGL | 
 | 690 |         //    implementation is reacting to the transform hint coming back from | 
 | 691 |         //    SurfaceFlinger), the surface damage needs to be rotated the | 
 | 692 |         //    opposite direction, since it was generated assuming an unrotated | 
 | 693 |         //    buffer (the app doesn't know that the EGL implementation is | 
 | 694 |         //    reacting to the transform hint behind its back). The | 
 | 695 |         //    transformations in the switch statement below apply those | 
 | 696 |         //    complementary rotations (e.g., if 90 degrees, rotate 270 degrees). | 
 | 697 |  | 
 | 698 |         int width = buffer->width; | 
| Dan Stoza | 0e65e6c | 2015-05-26 13:22:27 -0700 | [diff] [blame] | 699 |         int height = buffer->height; | 
| Dan Stoza | db4850c | 2015-06-25 16:10:18 -0700 | [diff] [blame] | 700 |         bool rotated90 = (mTransform ^ mStickyTransform) & | 
 | 701 |                 NATIVE_WINDOW_TRANSFORM_ROT_90; | 
 | 702 |         if (rotated90) { | 
 | 703 |             std::swap(width, height); | 
| Dan Stoza | 0e65e6c | 2015-05-26 13:22:27 -0700 | [diff] [blame] | 704 |         } | 
| Dan Stoza | db4850c | 2015-06-25 16:10:18 -0700 | [diff] [blame] | 705 |  | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 706 |         Region flippedRegion; | 
 | 707 |         for (auto rect : mDirtyRegion) { | 
| Dan Stoza | db4850c | 2015-06-25 16:10:18 -0700 | [diff] [blame] | 708 |             int left = rect.left; | 
 | 709 |             int right = rect.right; | 
 | 710 |             int top = height - rect.bottom; // Flip from OpenGL convention | 
 | 711 |             int bottom = height - rect.top; // Flip from OpenGL convention | 
 | 712 |             switch (mTransform ^ mStickyTransform) { | 
 | 713 |                 case NATIVE_WINDOW_TRANSFORM_ROT_90: { | 
 | 714 |                     // Rotate 270 degrees | 
 | 715 |                     Rect flippedRect{top, width - right, bottom, width - left}; | 
 | 716 |                     flippedRegion.orSelf(flippedRect); | 
 | 717 |                     break; | 
 | 718 |                 } | 
 | 719 |                 case NATIVE_WINDOW_TRANSFORM_ROT_180: { | 
 | 720 |                     // Rotate 180 degrees | 
 | 721 |                     Rect flippedRect{width - right, height - bottom, | 
 | 722 |                             width - left, height - top}; | 
 | 723 |                     flippedRegion.orSelf(flippedRect); | 
 | 724 |                     break; | 
 | 725 |                 } | 
 | 726 |                 case NATIVE_WINDOW_TRANSFORM_ROT_270: { | 
 | 727 |                     // Rotate 90 degrees | 
 | 728 |                     Rect flippedRect{height - bottom, left, | 
 | 729 |                             height - top, right}; | 
 | 730 |                     flippedRegion.orSelf(flippedRect); | 
 | 731 |                     break; | 
 | 732 |                 } | 
 | 733 |                 default: { | 
 | 734 |                     Rect flippedRect{left, top, right, bottom}; | 
 | 735 |                     flippedRegion.orSelf(flippedRect); | 
 | 736 |                     break; | 
 | 737 |                 } | 
 | 738 |             } | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 739 |         } | 
 | 740 |  | 
 | 741 |         input.setSurfaceDamage(flippedRegion); | 
 | 742 |     } | 
 | 743 |  | 
| Dan Stoza | 70ccba5 | 2016-07-01 14:00:40 -0700 | [diff] [blame] | 744 |     nsecs_t now = systemTime(); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 745 |     status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output); | 
| Dan Stoza | 70ccba5 | 2016-07-01 14:00:40 -0700 | [diff] [blame] | 746 |     mLastQueueDuration = systemTime() - now; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 747 |     if (err != OK)  { | 
 | 748 |         ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err); | 
 | 749 |     } | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 750 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 751 |     if (mEnableFrameTimestamps) { | 
| Brian Anderson | 3da8d27 | 2016-07-28 16:20:47 -0700 | [diff] [blame] | 752 |         mFrameEventHistory->applyDelta(output.frameTimestamps); | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 753 |         // Update timestamps with the local acquire fence. | 
 | 754 |         // The consumer doesn't send it back to prevent us from having two | 
 | 755 |         // file descriptors of the same fence. | 
| Brian Anderson | 3da8d27 | 2016-07-28 16:20:47 -0700 | [diff] [blame] | 756 |         mFrameEventHistory->updateAcquireFence(mNextFrameNumber, | 
| Brian Anderson | 3d4039d | 2016-09-23 16:31:30 -0700 | [diff] [blame] | 757 |                 std::make_shared<FenceTime>(std::move(fence))); | 
 | 758 |  | 
 | 759 |         // Cache timestamps of signaled fences so we can close their file | 
 | 760 |         // descriptors. | 
| Brian Anderson | 3da8d27 | 2016-07-28 16:20:47 -0700 | [diff] [blame] | 761 |         mFrameEventHistory->updateSignalTimes(); | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 762 |     } | 
 | 763 |  | 
| Brian Anderson | 50143b3 | 2016-09-30 14:01:24 -0700 | [diff] [blame] | 764 |     mLastFrameNumber = mNextFrameNumber; | 
 | 765 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 766 |     mDefaultWidth = output.width; | 
 | 767 |     mDefaultHeight = output.height; | 
 | 768 |     mNextFrameNumber = output.nextFrameNumber; | 
| tedbo | 1e7fa9e | 2011-06-22 15:52:53 -0700 | [diff] [blame] | 769 |  | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 770 |     // Disable transform hint if sticky transform is set. | 
 | 771 |     if (mStickyTransform == 0) { | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 772 |         mTransformHint = output.transformHint; | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 773 |     } | 
 | 774 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 775 |     mConsumerRunningBehind = (output.numPendingBuffers >= 2); | 
| Mathias Agopian | 631f358 | 2010-05-25 17:51:34 -0700 | [diff] [blame] | 776 |  | 
| Dan Stoza | c62acbd | 2015-04-21 16:42:49 -0700 | [diff] [blame] | 777 |     if (!mConnectedToCpu) { | 
 | 778 |         // Clear surface damage back to full-buffer | 
 | 779 |         mDirtyRegion = Region::INVALID_REGION; | 
 | 780 |     } | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 781 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 782 |     if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) { | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 783 |         mSharedBufferHasBeenQueued = true; | 
 | 784 |     } | 
 | 785 |  | 
| Robert Carr | 9f31e29 | 2016-04-11 11:15:32 -0700 | [diff] [blame] | 786 |     mQueueBufferCondition.broadcast(); | 
 | 787 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 788 |     return err; | 
 | 789 | } | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 790 |  | 
| Brian Anderson | 6b37671 | 2017-04-04 10:51:39 -0700 | [diff] [blame] | 791 | void Surface::querySupportedTimestampsLocked() const { | 
 | 792 |     // mMutex must be locked when calling this method. | 
 | 793 |  | 
 | 794 |     if (mQueriedSupportedTimestamps) { | 
 | 795 |         return; | 
 | 796 |     } | 
 | 797 |     mQueriedSupportedTimestamps = true; | 
 | 798 |  | 
 | 799 |     std::vector<FrameEvent> supportedFrameTimestamps; | 
 | 800 |     status_t err = composerService()->getSupportedFrameTimestamps( | 
 | 801 |             &supportedFrameTimestamps); | 
 | 802 |  | 
 | 803 |     if (err != NO_ERROR) { | 
 | 804 |         return; | 
 | 805 |     } | 
 | 806 |  | 
 | 807 |     for (auto sft : supportedFrameTimestamps) { | 
 | 808 |         if (sft == FrameEvent::DISPLAY_PRESENT) { | 
 | 809 |             mFrameTimestampsSupportsPresent = true; | 
 | 810 |         } | 
 | 811 |     } | 
 | 812 | } | 
 | 813 |  | 
| Mathias Agopian | a67932f | 2011-04-20 14:20:59 -0700 | [diff] [blame] | 814 | int Surface::query(int what, int* value) const { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 815 |     ATRACE_CALL(); | 
 | 816 |     ALOGV("Surface::query"); | 
 | 817 |     { // scope for the lock | 
 | 818 |         Mutex::Autolock lock(mMutex); | 
 | 819 |         switch (what) { | 
 | 820 |             case NATIVE_WINDOW_FORMAT: | 
 | 821 |                 if (mReqFormat) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 822 |                     *value = static_cast<int>(mReqFormat); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 823 |                     return NO_ERROR; | 
 | 824 |                 } | 
 | 825 |                 break; | 
 | 826 |             case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: { | 
| Brian Anderson | 3da8d27 | 2016-07-28 16:20:47 -0700 | [diff] [blame] | 827 |                 if (composerService()->authenticateSurfaceTexture( | 
 | 828 |                         mGraphicBufferProducer)) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 829 |                     *value = 1; | 
 | 830 |                 } else { | 
 | 831 |                     *value = 0; | 
 | 832 |                 } | 
 | 833 |                 return NO_ERROR; | 
 | 834 |             } | 
 | 835 |             case NATIVE_WINDOW_CONCRETE_TYPE: | 
 | 836 |                 *value = NATIVE_WINDOW_SURFACE; | 
 | 837 |                 return NO_ERROR; | 
 | 838 |             case NATIVE_WINDOW_DEFAULT_WIDTH: | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 839 |                 *value = static_cast<int>( | 
 | 840 |                         mUserWidth ? mUserWidth : mDefaultWidth); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 841 |                 return NO_ERROR; | 
 | 842 |             case NATIVE_WINDOW_DEFAULT_HEIGHT: | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 843 |                 *value = static_cast<int>( | 
 | 844 |                         mUserHeight ? mUserHeight : mDefaultHeight); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 845 |                 return NO_ERROR; | 
 | 846 |             case NATIVE_WINDOW_TRANSFORM_HINT: | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 847 |                 *value = static_cast<int>(mTransformHint); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 848 |                 return NO_ERROR; | 
 | 849 |             case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: { | 
 | 850 |                 status_t err = NO_ERROR; | 
 | 851 |                 if (!mConsumerRunningBehind) { | 
 | 852 |                     *value = 0; | 
 | 853 |                 } else { | 
 | 854 |                     err = mGraphicBufferProducer->query(what, value); | 
 | 855 |                     if (err == NO_ERROR) { | 
 | 856 |                         mConsumerRunningBehind = *value; | 
 | 857 |                     } | 
 | 858 |                 } | 
 | 859 |                 return err; | 
 | 860 |             } | 
| Ian Elliott | a2eb34c | 2017-07-18 11:05:49 -0600 | [diff] [blame] | 861 |             case NATIVE_WINDOW_BUFFER_AGE: { | 
 | 862 |                 if (mBufferAge > INT32_MAX) { | 
 | 863 |                     *value = 0; | 
 | 864 |                 } else { | 
 | 865 |                     *value = static_cast<int32_t>(mBufferAge); | 
 | 866 |                 } | 
 | 867 |                 return NO_ERROR; | 
 | 868 |             } | 
| Dan Stoza | 70ccba5 | 2016-07-01 14:00:40 -0700 | [diff] [blame] | 869 |             case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: { | 
 | 870 |                 int64_t durationUs = mLastDequeueDuration / 1000; | 
 | 871 |                 *value = durationUs > std::numeric_limits<int>::max() ? | 
 | 872 |                         std::numeric_limits<int>::max() : | 
 | 873 |                         static_cast<int>(durationUs); | 
 | 874 |                 return NO_ERROR; | 
 | 875 |             } | 
 | 876 |             case NATIVE_WINDOW_LAST_QUEUE_DURATION: { | 
 | 877 |                 int64_t durationUs = mLastQueueDuration / 1000; | 
 | 878 |                 *value = durationUs > std::numeric_limits<int>::max() ? | 
 | 879 |                         std::numeric_limits<int>::max() : | 
 | 880 |                         static_cast<int>(durationUs); | 
 | 881 |                 return NO_ERROR; | 
 | 882 |             } | 
| Brian Anderson | 6b37671 | 2017-04-04 10:51:39 -0700 | [diff] [blame] | 883 |             case NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT: { | 
 | 884 |                 querySupportedTimestampsLocked(); | 
 | 885 |                 *value = mFrameTimestampsSupportsPresent ? 1 : 0; | 
 | 886 |                 return NO_ERROR; | 
 | 887 |             } | 
| Mathias Agopian | 10e9ab5 | 2017-03-08 15:02:55 -0800 | [diff] [blame] | 888 |             case NATIVE_WINDOW_IS_VALID: { | 
 | 889 |                 *value = mGraphicBufferProducer != nullptr ? 1 : 0; | 
 | 890 |                 return NO_ERROR; | 
 | 891 |             } | 
| Peiyong Lin | 654f87b | 2018-01-30 14:21:33 -0800 | [diff] [blame] | 892 |             case NATIVE_WINDOW_DATASPACE: { | 
 | 893 |                 *value = static_cast<int>(mDataSpace); | 
 | 894 |                 return NO_ERROR; | 
 | 895 |             } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 896 |         } | 
| Jamie Gennis | 391bbe2 | 2011-03-14 15:00:06 -0700 | [diff] [blame] | 897 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 898 |     return mGraphicBufferProducer->query(what, value); | 
| Eino-Ville Talvala | 1d01a12 | 2011-02-18 11:02:42 -0800 | [diff] [blame] | 899 | } | 
 | 900 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 901 | int Surface::perform(int operation, va_list args) | 
 | 902 | { | 
 | 903 |     int res = NO_ERROR; | 
 | 904 |     switch (operation) { | 
 | 905 |     case NATIVE_WINDOW_CONNECT: | 
 | 906 |         // deprecated. must return NO_ERROR. | 
 | 907 |         break; | 
 | 908 |     case NATIVE_WINDOW_DISCONNECT: | 
 | 909 |         // deprecated. must return NO_ERROR. | 
 | 910 |         break; | 
 | 911 |     case NATIVE_WINDOW_SET_USAGE: | 
 | 912 |         res = dispatchSetUsage(args); | 
 | 913 |         break; | 
 | 914 |     case NATIVE_WINDOW_SET_CROP: | 
 | 915 |         res = dispatchSetCrop(args); | 
 | 916 |         break; | 
 | 917 |     case NATIVE_WINDOW_SET_BUFFER_COUNT: | 
 | 918 |         res = dispatchSetBufferCount(args); | 
 | 919 |         break; | 
 | 920 |     case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: | 
 | 921 |         res = dispatchSetBuffersGeometry(args); | 
 | 922 |         break; | 
 | 923 |     case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: | 
 | 924 |         res = dispatchSetBuffersTransform(args); | 
 | 925 |         break; | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 926 |     case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM: | 
 | 927 |         res = dispatchSetBuffersStickyTransform(args); | 
 | 928 |         break; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 929 |     case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: | 
 | 930 |         res = dispatchSetBuffersTimestamp(args); | 
 | 931 |         break; | 
 | 932 |     case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: | 
 | 933 |         res = dispatchSetBuffersDimensions(args); | 
 | 934 |         break; | 
 | 935 |     case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS: | 
 | 936 |         res = dispatchSetBuffersUserDimensions(args); | 
 | 937 |         break; | 
 | 938 |     case NATIVE_WINDOW_SET_BUFFERS_FORMAT: | 
 | 939 |         res = dispatchSetBuffersFormat(args); | 
 | 940 |         break; | 
 | 941 |     case NATIVE_WINDOW_LOCK: | 
 | 942 |         res = dispatchLock(args); | 
 | 943 |         break; | 
 | 944 |     case NATIVE_WINDOW_UNLOCK_AND_POST: | 
 | 945 |         res = dispatchUnlockAndPost(args); | 
 | 946 |         break; | 
 | 947 |     case NATIVE_WINDOW_SET_SCALING_MODE: | 
 | 948 |         res = dispatchSetScalingMode(args); | 
 | 949 |         break; | 
 | 950 |     case NATIVE_WINDOW_API_CONNECT: | 
 | 951 |         res = dispatchConnect(args); | 
 | 952 |         break; | 
 | 953 |     case NATIVE_WINDOW_API_DISCONNECT: | 
 | 954 |         res = dispatchDisconnect(args); | 
 | 955 |         break; | 
| Rachad | 7cb0d39 | 2014-07-29 17:53:53 -0700 | [diff] [blame] | 956 |     case NATIVE_WINDOW_SET_SIDEBAND_STREAM: | 
 | 957 |         res = dispatchSetSidebandStream(args); | 
 | 958 |         break; | 
| Eino-Ville Talvala | 82c6bcc | 2015-02-19 16:10:43 -0800 | [diff] [blame] | 959 |     case NATIVE_WINDOW_SET_BUFFERS_DATASPACE: | 
 | 960 |         res = dispatchSetBuffersDataSpace(args); | 
 | 961 |         break; | 
| Courtney Goeltzenleuchter | 9bad0d7 | 2017-12-19 12:34:34 -0700 | [diff] [blame] | 962 |     case NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA: | 
 | 963 |         res = dispatchSetBuffersSmpte2086Metadata(args); | 
 | 964 |         break; | 
 | 965 |     case NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA: | 
 | 966 |         res = dispatchSetBuffersCta8613Metadata(args); | 
 | 967 |         break; | 
| Valerie Hau | a82679d | 2018-11-21 09:31:43 -0800 | [diff] [blame] | 968 |     case NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA: | 
 | 969 |         res = dispatchSetBuffersHdr10PlusMetadata(args); | 
 | 970 |         break; | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 971 |     case NATIVE_WINDOW_SET_SURFACE_DAMAGE: | 
 | 972 |         res = dispatchSetSurfaceDamage(args); | 
 | 973 |         break; | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 974 |     case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE: | 
 | 975 |         res = dispatchSetSharedBufferMode(args); | 
| Pablo Ceballos | ccdfd60 | 2015-10-07 15:05:45 -0700 | [diff] [blame] | 976 |         break; | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 977 |     case NATIVE_WINDOW_SET_AUTO_REFRESH: | 
 | 978 |         res = dispatchSetAutoRefresh(args); | 
 | 979 |         break; | 
| Brian Anderson | 0a61b0c | 2016-12-07 14:55:56 -0800 | [diff] [blame] | 980 |     case NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION: | 
 | 981 |         res = dispatchGetDisplayRefreshCycleDuration(args); | 
 | 982 |         break; | 
| Brian Anderson | 1049d1d | 2016-12-16 17:25:57 -0800 | [diff] [blame] | 983 |     case NATIVE_WINDOW_GET_NEXT_FRAME_ID: | 
 | 984 |         res = dispatchGetNextFrameId(args); | 
 | 985 |         break; | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 986 |     case NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS: | 
 | 987 |         res = dispatchEnableFrameTimestamps(args); | 
 | 988 |         break; | 
| Brian Anderson | 0a61b0c | 2016-12-07 14:55:56 -0800 | [diff] [blame] | 989 |     case NATIVE_WINDOW_GET_COMPOSITOR_TIMING: | 
 | 990 |         res = dispatchGetCompositorTiming(args); | 
 | 991 |         break; | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 992 |     case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS: | 
 | 993 |         res = dispatchGetFrameTimestamps(args); | 
 | 994 |         break; | 
| Courtney Goeltzenleuchter | 1eb1b27 | 2017-02-02 16:51:06 -0700 | [diff] [blame] | 995 |     case NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT: | 
 | 996 |         res = dispatchGetWideColorSupport(args); | 
 | 997 |         break; | 
| Courtney Goeltzenleuchter | c5b97c5 | 2017-02-26 14:47:13 -0700 | [diff] [blame] | 998 |     case NATIVE_WINDOW_GET_HDR_SUPPORT: | 
 | 999 |         res = dispatchGetHdrSupport(args); | 
 | 1000 |         break; | 
| Mathias Agopian | cb496ac | 2017-05-22 14:21:00 -0700 | [diff] [blame] | 1001 |     case NATIVE_WINDOW_SET_USAGE64: | 
 | 1002 |         res = dispatchSetUsage64(args); | 
 | 1003 |         break; | 
| Chia-I Wu | e2786ea | 2017-08-07 10:36:08 -0700 | [diff] [blame] | 1004 |     case NATIVE_WINDOW_GET_CONSUMER_USAGE64: | 
 | 1005 |         res = dispatchGetConsumerUsage64(args); | 
 | 1006 |         break; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1007 |     default: | 
 | 1008 |         res = NAME_NOT_FOUND; | 
 | 1009 |         break; | 
 | 1010 |     } | 
 | 1011 |     return res; | 
 | 1012 | } | 
| Mathias Agopian | a138f89 | 2010-05-21 17:24:35 -0700 | [diff] [blame] | 1013 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1014 | int Surface::dispatchConnect(va_list args) { | 
 | 1015 |     int api = va_arg(args, int); | 
 | 1016 |     return connect(api); | 
 | 1017 | } | 
| Mathias Agopian | 55fa251 | 2010-03-11 15:06:54 -0800 | [diff] [blame] | 1018 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1019 | int Surface::dispatchDisconnect(va_list args) { | 
 | 1020 |     int api = va_arg(args, int); | 
 | 1021 |     return disconnect(api); | 
 | 1022 | } | 
 | 1023 |  | 
 | 1024 | int Surface::dispatchSetUsage(va_list args) { | 
| Mathias Agopian | cb496ac | 2017-05-22 14:21:00 -0700 | [diff] [blame] | 1025 |     uint64_t usage = va_arg(args, uint32_t); | 
 | 1026 |     return setUsage(usage); | 
 | 1027 | } | 
 | 1028 |  | 
 | 1029 | int Surface::dispatchSetUsage64(va_list args) { | 
 | 1030 |     uint64_t usage = va_arg(args, uint64_t); | 
 | 1031 |     return setUsage(usage); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1032 | } | 
 | 1033 |  | 
 | 1034 | int Surface::dispatchSetCrop(va_list args) { | 
 | 1035 |     android_native_rect_t const* rect = va_arg(args, android_native_rect_t*); | 
 | 1036 |     return setCrop(reinterpret_cast<Rect const*>(rect)); | 
 | 1037 | } | 
 | 1038 |  | 
 | 1039 | int Surface::dispatchSetBufferCount(va_list args) { | 
 | 1040 |     size_t bufferCount = va_arg(args, size_t); | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1041 |     return setBufferCount(static_cast<int32_t>(bufferCount)); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1042 | } | 
 | 1043 |  | 
 | 1044 | int Surface::dispatchSetBuffersGeometry(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1045 |     uint32_t width = va_arg(args, uint32_t); | 
 | 1046 |     uint32_t height = va_arg(args, uint32_t); | 
 | 1047 |     PixelFormat format = va_arg(args, PixelFormat); | 
 | 1048 |     int err = setBuffersDimensions(width, height); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1049 |     if (err != 0) { | 
 | 1050 |         return err; | 
 | 1051 |     } | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1052 |     return setBuffersFormat(format); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1053 | } | 
 | 1054 |  | 
 | 1055 | int Surface::dispatchSetBuffersDimensions(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1056 |     uint32_t width = va_arg(args, uint32_t); | 
 | 1057 |     uint32_t height = va_arg(args, uint32_t); | 
 | 1058 |     return setBuffersDimensions(width, height); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1059 | } | 
 | 1060 |  | 
 | 1061 | int Surface::dispatchSetBuffersUserDimensions(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1062 |     uint32_t width = va_arg(args, uint32_t); | 
 | 1063 |     uint32_t height = va_arg(args, uint32_t); | 
 | 1064 |     return setBuffersUserDimensions(width, height); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1065 | } | 
 | 1066 |  | 
 | 1067 | int Surface::dispatchSetBuffersFormat(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1068 |     PixelFormat format = va_arg(args, PixelFormat); | 
 | 1069 |     return setBuffersFormat(format); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1070 | } | 
 | 1071 |  | 
 | 1072 | int Surface::dispatchSetScalingMode(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1073 |     int mode = va_arg(args, int); | 
 | 1074 |     return setScalingMode(mode); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1075 | } | 
 | 1076 |  | 
 | 1077 | int Surface::dispatchSetBuffersTransform(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1078 |     uint32_t transform = va_arg(args, uint32_t); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1079 |     return setBuffersTransform(transform); | 
 | 1080 | } | 
 | 1081 |  | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 1082 | int Surface::dispatchSetBuffersStickyTransform(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1083 |     uint32_t transform = va_arg(args, uint32_t); | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 1084 |     return setBuffersStickyTransform(transform); | 
 | 1085 | } | 
 | 1086 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1087 | int Surface::dispatchSetBuffersTimestamp(va_list args) { | 
 | 1088 |     int64_t timestamp = va_arg(args, int64_t); | 
 | 1089 |     return setBuffersTimestamp(timestamp); | 
 | 1090 | } | 
 | 1091 |  | 
 | 1092 | int Surface::dispatchLock(va_list args) { | 
 | 1093 |     ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*); | 
 | 1094 |     ARect* inOutDirtyBounds = va_arg(args, ARect*); | 
 | 1095 |     return lock(outBuffer, inOutDirtyBounds); | 
 | 1096 | } | 
 | 1097 |  | 
| Igor Murashkin | 7d2d160 | 2013-11-12 18:02:20 -0800 | [diff] [blame] | 1098 | int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1099 |     return unlockAndPost(); | 
 | 1100 | } | 
 | 1101 |  | 
| Rachad | 7cb0d39 | 2014-07-29 17:53:53 -0700 | [diff] [blame] | 1102 | int Surface::dispatchSetSidebandStream(va_list args) { | 
 | 1103 |     native_handle_t* sH = va_arg(args, native_handle_t*); | 
 | 1104 |     sp<NativeHandle> sidebandHandle = NativeHandle::create(sH, false); | 
 | 1105 |     setSidebandStream(sidebandHandle); | 
 | 1106 |     return OK; | 
 | 1107 | } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1108 |  | 
| Eino-Ville Talvala | 82c6bcc | 2015-02-19 16:10:43 -0800 | [diff] [blame] | 1109 | int Surface::dispatchSetBuffersDataSpace(va_list args) { | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 1110 |     Dataspace dataspace = static_cast<Dataspace>(va_arg(args, int)); | 
| Eino-Ville Talvala | 82c6bcc | 2015-02-19 16:10:43 -0800 | [diff] [blame] | 1111 |     return setBuffersDataSpace(dataspace); | 
 | 1112 | } | 
 | 1113 |  | 
| Courtney Goeltzenleuchter | 9bad0d7 | 2017-12-19 12:34:34 -0700 | [diff] [blame] | 1114 | int Surface::dispatchSetBuffersSmpte2086Metadata(va_list args) { | 
 | 1115 |     const android_smpte2086_metadata* metadata = | 
 | 1116 |         va_arg(args, const android_smpte2086_metadata*); | 
 | 1117 |     return setBuffersSmpte2086Metadata(metadata); | 
 | 1118 | } | 
 | 1119 |  | 
 | 1120 | int Surface::dispatchSetBuffersCta8613Metadata(va_list args) { | 
 | 1121 |     const android_cta861_3_metadata* metadata = | 
 | 1122 |         va_arg(args, const android_cta861_3_metadata*); | 
 | 1123 |     return setBuffersCta8613Metadata(metadata); | 
 | 1124 | } | 
 | 1125 |  | 
| Valerie Hau | a82679d | 2018-11-21 09:31:43 -0800 | [diff] [blame] | 1126 | int Surface::dispatchSetBuffersHdr10PlusMetadata(va_list args) { | 
 | 1127 |     const size_t size = va_arg(args, size_t); | 
 | 1128 |     const uint8_t* metadata = va_arg(args, const uint8_t*); | 
 | 1129 |     return setBuffersHdr10PlusMetadata(size, metadata); | 
 | 1130 | } | 
 | 1131 |  | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 1132 | int Surface::dispatchSetSurfaceDamage(va_list args) { | 
 | 1133 |     android_native_rect_t* rects = va_arg(args, android_native_rect_t*); | 
 | 1134 |     size_t numRects = va_arg(args, size_t); | 
 | 1135 |     setSurfaceDamage(rects, numRects); | 
 | 1136 |     return NO_ERROR; | 
 | 1137 | } | 
 | 1138 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 1139 | int Surface::dispatchSetSharedBufferMode(va_list args) { | 
 | 1140 |     bool sharedBufferMode = va_arg(args, int); | 
 | 1141 |     return setSharedBufferMode(sharedBufferMode); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1142 | } | 
 | 1143 |  | 
 | 1144 | int Surface::dispatchSetAutoRefresh(va_list args) { | 
 | 1145 |     bool autoRefresh = va_arg(args, int); | 
 | 1146 |     return setAutoRefresh(autoRefresh); | 
| Pablo Ceballos | ccdfd60 | 2015-10-07 15:05:45 -0700 | [diff] [blame] | 1147 | } | 
 | 1148 |  | 
| Brian Anderson | 0a61b0c | 2016-12-07 14:55:56 -0800 | [diff] [blame] | 1149 | int Surface::dispatchGetDisplayRefreshCycleDuration(va_list args) { | 
 | 1150 |     nsecs_t* outRefreshDuration = va_arg(args, int64_t*); | 
 | 1151 |     return getDisplayRefreshCycleDuration(outRefreshDuration); | 
 | 1152 | } | 
 | 1153 |  | 
| Brian Anderson | 1049d1d | 2016-12-16 17:25:57 -0800 | [diff] [blame] | 1154 | int Surface::dispatchGetNextFrameId(va_list args) { | 
 | 1155 |     uint64_t* nextFrameId = va_arg(args, uint64_t*); | 
 | 1156 |     *nextFrameId = getNextFrameNumber(); | 
 | 1157 |     return NO_ERROR; | 
 | 1158 | } | 
 | 1159 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 1160 | int Surface::dispatchEnableFrameTimestamps(va_list args) { | 
 | 1161 |     bool enable = va_arg(args, int); | 
 | 1162 |     enableFrameTimestamps(enable); | 
 | 1163 |     return NO_ERROR; | 
 | 1164 | } | 
 | 1165 |  | 
| Brian Anderson | 0a61b0c | 2016-12-07 14:55:56 -0800 | [diff] [blame] | 1166 | int Surface::dispatchGetCompositorTiming(va_list args) { | 
 | 1167 |     nsecs_t* compositeDeadline = va_arg(args, int64_t*); | 
 | 1168 |     nsecs_t* compositeInterval = va_arg(args, int64_t*); | 
 | 1169 |     nsecs_t* compositeToPresentLatency = va_arg(args, int64_t*); | 
 | 1170 |     return getCompositorTiming(compositeDeadline, compositeInterval, | 
 | 1171 |             compositeToPresentLatency); | 
 | 1172 | } | 
 | 1173 |  | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 1174 | int Surface::dispatchGetFrameTimestamps(va_list args) { | 
| Brian Anderson | 1049d1d | 2016-12-16 17:25:57 -0800 | [diff] [blame] | 1175 |     uint64_t frameId = va_arg(args, uint64_t); | 
| Brian Anderson | dbd0ea8 | 2016-07-22 09:38:59 -0700 | [diff] [blame] | 1176 |     nsecs_t* outRequestedPresentTime = va_arg(args, int64_t*); | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 1177 |     nsecs_t* outAcquireTime = va_arg(args, int64_t*); | 
| Brian Anderson | f7fd56a | 2016-09-02 10:10:04 -0700 | [diff] [blame] | 1178 |     nsecs_t* outLatchTime = va_arg(args, int64_t*); | 
 | 1179 |     nsecs_t* outFirstRefreshStartTime = va_arg(args, int64_t*); | 
 | 1180 |     nsecs_t* outLastRefreshStartTime = va_arg(args, int64_t*); | 
| Brian Anderson | b04c6f0 | 2016-10-21 12:57:46 -0700 | [diff] [blame] | 1181 |     nsecs_t* outGpuCompositionDoneTime = va_arg(args, int64_t*); | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 1182 |     nsecs_t* outDisplayPresentTime = va_arg(args, int64_t*); | 
| Brian Anderson | f7fd56a | 2016-09-02 10:10:04 -0700 | [diff] [blame] | 1183 |     nsecs_t* outDequeueReadyTime = va_arg(args, int64_t*); | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 1184 |     nsecs_t* outReleaseTime = va_arg(args, int64_t*); | 
| Brian Anderson | 1049d1d | 2016-12-16 17:25:57 -0800 | [diff] [blame] | 1185 |     return getFrameTimestamps(frameId, | 
| Brian Anderson | f7fd56a | 2016-09-02 10:10:04 -0700 | [diff] [blame] | 1186 |             outRequestedPresentTime, outAcquireTime, outLatchTime, | 
 | 1187 |             outFirstRefreshStartTime, outLastRefreshStartTime, | 
| Brian Anderson | b04c6f0 | 2016-10-21 12:57:46 -0700 | [diff] [blame] | 1188 |             outGpuCompositionDoneTime, outDisplayPresentTime, | 
| Brian Anderson | 4e606e3 | 2017-03-16 15:34:57 -0700 | [diff] [blame] | 1189 |             outDequeueReadyTime, outReleaseTime); | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 1190 | } | 
 | 1191 |  | 
| Courtney Goeltzenleuchter | 1eb1b27 | 2017-02-02 16:51:06 -0700 | [diff] [blame] | 1192 | int Surface::dispatchGetWideColorSupport(va_list args) { | 
 | 1193 |     bool* outSupport = va_arg(args, bool*); | 
 | 1194 |     return getWideColorSupport(outSupport); | 
 | 1195 | } | 
 | 1196 |  | 
| Courtney Goeltzenleuchter | c5b97c5 | 2017-02-26 14:47:13 -0700 | [diff] [blame] | 1197 | int Surface::dispatchGetHdrSupport(va_list args) { | 
 | 1198 |     bool* outSupport = va_arg(args, bool*); | 
 | 1199 |     return getHdrSupport(outSupport); | 
 | 1200 | } | 
 | 1201 |  | 
| Chia-I Wu | e2786ea | 2017-08-07 10:36:08 -0700 | [diff] [blame] | 1202 | int Surface::dispatchGetConsumerUsage64(va_list args) { | 
 | 1203 |     uint64_t* usage = va_arg(args, uint64_t*); | 
 | 1204 |     return getConsumerUsage(usage); | 
 | 1205 | } | 
 | 1206 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1207 | int Surface::connect(int api) { | 
| Dan Stoza | 966b98b | 2015-03-02 22:12:37 -0800 | [diff] [blame] | 1208 |     static sp<IProducerListener> listener = new DummyProducerListener(); | 
 | 1209 |     return connect(api, listener); | 
 | 1210 | } | 
 | 1211 |  | 
 | 1212 | int Surface::connect(int api, const sp<IProducerListener>& listener) { | 
| Yin-Chia Yeh | e572fd7 | 2017-03-28 19:07:39 -0700 | [diff] [blame] | 1213 |     return connect(api, listener, false); | 
 | 1214 | } | 
 | 1215 |  | 
 | 1216 | int Surface::connect( | 
 | 1217 |         int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1218 |     ATRACE_CALL(); | 
 | 1219 |     ALOGV("Surface::connect"); | 
 | 1220 |     Mutex::Autolock lock(mMutex); | 
 | 1221 |     IGraphicBufferProducer::QueueBufferOutput output; | 
| Yin-Chia Yeh | e572fd7 | 2017-03-28 19:07:39 -0700 | [diff] [blame] | 1222 |     mReportRemovedBuffers = reportBufferRemoval; | 
| Dan Stoza | f0eaf25 | 2014-03-21 13:05:51 -0700 | [diff] [blame] | 1223 |     int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1224 |     if (err == NO_ERROR) { | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 1225 |         mDefaultWidth = output.width; | 
 | 1226 |         mDefaultHeight = output.height; | 
 | 1227 |         mNextFrameNumber = output.nextFrameNumber; | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 1228 |  | 
 | 1229 |         // Disable transform hint if sticky transform is set. | 
 | 1230 |         if (mStickyTransform == 0) { | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 1231 |             mTransformHint = output.transformHint; | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 1232 |         } | 
 | 1233 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 1234 |         mConsumerRunningBehind = (output.numPendingBuffers >= 2); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1235 |     } | 
 | 1236 |     if (!err && api == NATIVE_WINDOW_API_CPU) { | 
 | 1237 |         mConnectedToCpu = true; | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 1238 |         // Clear the dirty region in case we're switching from a non-CPU API | 
 | 1239 |         mDirtyRegion.clear(); | 
 | 1240 |     } else if (!err) { | 
 | 1241 |         // Initialize the dirty region for tracking surface damage | 
 | 1242 |         mDirtyRegion = Region::INVALID_REGION; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1243 |     } | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 1244 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1245 |     return err; | 
 | 1246 | } | 
 | 1247 |  | 
| Mathias Agopian | 365857d | 2013-09-11 19:35:45 -0700 | [diff] [blame] | 1248 |  | 
| Robert Carr | 97b9c86 | 2016-09-08 13:54:35 -0700 | [diff] [blame] | 1249 | int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1250 |     ATRACE_CALL(); | 
 | 1251 |     ALOGV("Surface::disconnect"); | 
 | 1252 |     Mutex::Autolock lock(mMutex); | 
| Yin-Chia Yeh | e572fd7 | 2017-03-28 19:07:39 -0700 | [diff] [blame] | 1253 |     mRemovedBuffers.clear(); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1254 |     mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; | 
 | 1255 |     mSharedBufferHasBeenQueued = false; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1256 |     freeAllBuffers(); | 
| Robert Carr | 97b9c86 | 2016-09-08 13:54:35 -0700 | [diff] [blame] | 1257 |     int err = mGraphicBufferProducer->disconnect(api, mode); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1258 |     if (!err) { | 
 | 1259 |         mReqFormat = 0; | 
 | 1260 |         mReqWidth = 0; | 
 | 1261 |         mReqHeight = 0; | 
 | 1262 |         mReqUsage = 0; | 
 | 1263 |         mCrop.clear(); | 
 | 1264 |         mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; | 
 | 1265 |         mTransform = 0; | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 1266 |         mStickyTransform = 0; | 
 | 1267 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1268 |         if (api == NATIVE_WINDOW_API_CPU) { | 
 | 1269 |             mConnectedToCpu = false; | 
 | 1270 |         } | 
 | 1271 |     } | 
 | 1272 |     return err; | 
 | 1273 | } | 
 | 1274 |  | 
| Dan Stoza | d9c4971 | 2015-04-27 11:06:01 -0700 | [diff] [blame] | 1275 | int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer, | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1276 |         sp<Fence>* outFence) { | 
 | 1277 |     ATRACE_CALL(); | 
 | 1278 |     ALOGV("Surface::detachNextBuffer"); | 
 | 1279 |  | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1280 |     if (outBuffer == nullptr || outFence == nullptr) { | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1281 |         return BAD_VALUE; | 
 | 1282 |     } | 
 | 1283 |  | 
 | 1284 |     Mutex::Autolock lock(mMutex); | 
| Yin-Chia Yeh | 1f2af5c | 2017-05-11 16:54:04 -0700 | [diff] [blame] | 1285 |     if (mReportRemovedBuffers) { | 
 | 1286 |         mRemovedBuffers.clear(); | 
 | 1287 |     } | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1288 |  | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1289 |     sp<GraphicBuffer> buffer(nullptr); | 
 | 1290 |     sp<Fence> fence(nullptr); | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1291 |     status_t result = mGraphicBufferProducer->detachNextBuffer( | 
 | 1292 |             &buffer, &fence); | 
 | 1293 |     if (result != NO_ERROR) { | 
 | 1294 |         return result; | 
 | 1295 |     } | 
 | 1296 |  | 
| Dan Stoza | d9c4971 | 2015-04-27 11:06:01 -0700 | [diff] [blame] | 1297 |     *outBuffer = buffer; | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1298 |     if (fence != nullptr && fence->isValid()) { | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1299 |         *outFence = fence; | 
 | 1300 |     } else { | 
 | 1301 |         *outFence = Fence::NO_FENCE; | 
 | 1302 |     } | 
 | 1303 |  | 
| Pablo Ceballos | 23b4abe | 2016-01-08 12:15:22 -0800 | [diff] [blame] | 1304 |     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1305 |         if (mSlots[i].buffer != nullptr && | 
| Shuzhen Wang | 55be505 | 2017-05-23 09:41:54 -0700 | [diff] [blame] | 1306 |                 mSlots[i].buffer->getId() == buffer->getId()) { | 
| Yin-Chia Yeh | e572fd7 | 2017-03-28 19:07:39 -0700 | [diff] [blame] | 1307 |             if (mReportRemovedBuffers) { | 
 | 1308 |                 mRemovedBuffers.push_back(mSlots[i].buffer); | 
 | 1309 |             } | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1310 |             mSlots[i].buffer = nullptr; | 
| Pablo Ceballos | 23b4abe | 2016-01-08 12:15:22 -0800 | [diff] [blame] | 1311 |         } | 
 | 1312 |     } | 
 | 1313 |  | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1314 |     return NO_ERROR; | 
 | 1315 | } | 
 | 1316 |  | 
 | 1317 | int Surface::attachBuffer(ANativeWindowBuffer* buffer) | 
 | 1318 | { | 
 | 1319 |     ATRACE_CALL(); | 
 | 1320 |     ALOGV("Surface::attachBuffer"); | 
 | 1321 |  | 
 | 1322 |     Mutex::Autolock lock(mMutex); | 
| Yin-Chia Yeh | 1f2af5c | 2017-05-11 16:54:04 -0700 | [diff] [blame] | 1323 |     if (mReportRemovedBuffers) { | 
 | 1324 |         mRemovedBuffers.clear(); | 
 | 1325 |     } | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1326 |  | 
 | 1327 |     sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer)); | 
| Dan Stoza | 812ed06 | 2015-06-02 15:45:22 -0700 | [diff] [blame] | 1328 |     uint32_t priorGeneration = graphicBuffer->mGenerationNumber; | 
 | 1329 |     graphicBuffer->mGenerationNumber = mGenerationNumber; | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1330 |     int32_t attachedSlot = -1; | 
| Mathias Agopian | cb496ac | 2017-05-22 14:21:00 -0700 | [diff] [blame] | 1331 |     status_t result = mGraphicBufferProducer->attachBuffer(&attachedSlot, graphicBuffer); | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1332 |     if (result != NO_ERROR) { | 
 | 1333 |         ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result); | 
| Dan Stoza | 812ed06 | 2015-06-02 15:45:22 -0700 | [diff] [blame] | 1334 |         graphicBuffer->mGenerationNumber = priorGeneration; | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1335 |         return result; | 
 | 1336 |     } | 
| Yin-Chia Yeh | e572fd7 | 2017-03-28 19:07:39 -0700 | [diff] [blame] | 1337 |     if (mReportRemovedBuffers && (mSlots[attachedSlot].buffer != nullptr)) { | 
| Yin-Chia Yeh | e572fd7 | 2017-03-28 19:07:39 -0700 | [diff] [blame] | 1338 |         mRemovedBuffers.push_back(mSlots[attachedSlot].buffer); | 
 | 1339 |     } | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1340 |     mSlots[attachedSlot].buffer = graphicBuffer; | 
 | 1341 |  | 
 | 1342 |     return NO_ERROR; | 
 | 1343 | } | 
 | 1344 |  | 
| Mathias Agopian | cb496ac | 2017-05-22 14:21:00 -0700 | [diff] [blame] | 1345 | int Surface::setUsage(uint64_t reqUsage) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1346 | { | 
 | 1347 |     ALOGV("Surface::setUsage"); | 
 | 1348 |     Mutex::Autolock lock(mMutex); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1349 |     if (reqUsage != mReqUsage) { | 
 | 1350 |         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; | 
 | 1351 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1352 |     mReqUsage = reqUsage; | 
 | 1353 |     return OK; | 
 | 1354 | } | 
 | 1355 |  | 
 | 1356 | int Surface::setCrop(Rect const* rect) | 
 | 1357 | { | 
 | 1358 |     ATRACE_CALL(); | 
 | 1359 |  | 
| Pablo Ceballos | 60d6922 | 2015-08-07 14:47:20 -0700 | [diff] [blame] | 1360 |     Rect realRect(Rect::EMPTY_RECT); | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1361 |     if (rect == nullptr || rect->isEmpty()) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1362 |         realRect.clear(); | 
 | 1363 |     } else { | 
 | 1364 |         realRect = *rect; | 
| Mathias Agopian | 55fa251 | 2010-03-11 15:06:54 -0800 | [diff] [blame] | 1365 |     } | 
 | 1366 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1367 |     ALOGV("Surface::setCrop rect=[%d %d %d %d]", | 
 | 1368 |             realRect.left, realRect.top, realRect.right, realRect.bottom); | 
 | 1369 |  | 
 | 1370 |     Mutex::Autolock lock(mMutex); | 
 | 1371 |     mCrop = realRect; | 
 | 1372 |     return NO_ERROR; | 
 | 1373 | } | 
 | 1374 |  | 
 | 1375 | int Surface::setBufferCount(int bufferCount) | 
 | 1376 | { | 
 | 1377 |     ATRACE_CALL(); | 
 | 1378 |     ALOGV("Surface::setBufferCount"); | 
 | 1379 |     Mutex::Autolock lock(mMutex); | 
 | 1380 |  | 
| Pablo Ceballos | e5b755a | 2015-08-13 16:18:19 -0700 | [diff] [blame] | 1381 |     status_t err = NO_ERROR; | 
 | 1382 |     if (bufferCount == 0) { | 
 | 1383 |         err = mGraphicBufferProducer->setMaxDequeuedBufferCount(1); | 
 | 1384 |     } else { | 
 | 1385 |         int minUndequeuedBuffers = 0; | 
 | 1386 |         err = mGraphicBufferProducer->query( | 
 | 1387 |                 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers); | 
 | 1388 |         if (err == NO_ERROR) { | 
 | 1389 |             err = mGraphicBufferProducer->setMaxDequeuedBufferCount( | 
 | 1390 |                     bufferCount - minUndequeuedBuffers); | 
 | 1391 |         } | 
 | 1392 |     } | 
| Mathias Agopian | 9014726 | 2010-01-22 11:47:55 -0800 | [diff] [blame] | 1393 |  | 
| Pablo Ceballos | e5b755a | 2015-08-13 16:18:19 -0700 | [diff] [blame] | 1394 |     ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s", | 
 | 1395 |              bufferCount, strerror(-err)); | 
 | 1396 |  | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 1397 |     return err; | 
 | 1398 | } | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 1399 |  | 
| Pablo Ceballos | fa45535 | 2015-08-12 17:47:47 -0700 | [diff] [blame] | 1400 | int Surface::setMaxDequeuedBufferCount(int maxDequeuedBuffers) { | 
 | 1401 |     ATRACE_CALL(); | 
 | 1402 |     ALOGV("Surface::setMaxDequeuedBufferCount"); | 
 | 1403 |     Mutex::Autolock lock(mMutex); | 
 | 1404 |  | 
 | 1405 |     status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount( | 
 | 1406 |             maxDequeuedBuffers); | 
 | 1407 |     ALOGE_IF(err, "IGraphicBufferProducer::setMaxDequeuedBufferCount(%d) " | 
 | 1408 |             "returned %s", maxDequeuedBuffers, strerror(-err)); | 
 | 1409 |  | 
| Pablo Ceballos | fa45535 | 2015-08-12 17:47:47 -0700 | [diff] [blame] | 1410 |     return err; | 
 | 1411 | } | 
 | 1412 |  | 
 | 1413 | int Surface::setAsyncMode(bool async) { | 
 | 1414 |     ATRACE_CALL(); | 
 | 1415 |     ALOGV("Surface::setAsyncMode"); | 
 | 1416 |     Mutex::Autolock lock(mMutex); | 
 | 1417 |  | 
 | 1418 |     status_t err = mGraphicBufferProducer->setAsyncMode(async); | 
 | 1419 |     ALOGE_IF(err, "IGraphicBufferProducer::setAsyncMode(%d) returned %s", | 
 | 1420 |             async, strerror(-err)); | 
 | 1421 |  | 
| Pablo Ceballos | fa45535 | 2015-08-12 17:47:47 -0700 | [diff] [blame] | 1422 |     return err; | 
 | 1423 | } | 
 | 1424 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 1425 | int Surface::setSharedBufferMode(bool sharedBufferMode) { | 
| Pablo Ceballos | ccdfd60 | 2015-10-07 15:05:45 -0700 | [diff] [blame] | 1426 |     ATRACE_CALL(); | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 1427 |     ALOGV("Surface::setSharedBufferMode (%d)", sharedBufferMode); | 
| Pablo Ceballos | ccdfd60 | 2015-10-07 15:05:45 -0700 | [diff] [blame] | 1428 |     Mutex::Autolock lock(mMutex); | 
 | 1429 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 1430 |     status_t err = mGraphicBufferProducer->setSharedBufferMode( | 
 | 1431 |             sharedBufferMode); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1432 |     if (err == NO_ERROR) { | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 1433 |         mSharedBufferMode = sharedBufferMode; | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1434 |     } | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 1435 |     ALOGE_IF(err, "IGraphicBufferProducer::setSharedBufferMode(%d) returned" | 
 | 1436 |             "%s", sharedBufferMode, strerror(-err)); | 
| Pablo Ceballos | ccdfd60 | 2015-10-07 15:05:45 -0700 | [diff] [blame] | 1437 |  | 
 | 1438 |     return err; | 
 | 1439 | } | 
 | 1440 |  | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1441 | int Surface::setAutoRefresh(bool autoRefresh) { | 
 | 1442 |     ATRACE_CALL(); | 
 | 1443 |     ALOGV("Surface::setAutoRefresh (%d)", autoRefresh); | 
 | 1444 |     Mutex::Autolock lock(mMutex); | 
 | 1445 |  | 
 | 1446 |     status_t err = mGraphicBufferProducer->setAutoRefresh(autoRefresh); | 
 | 1447 |     if (err == NO_ERROR) { | 
 | 1448 |         mAutoRefresh = autoRefresh; | 
 | 1449 |     } | 
 | 1450 |     ALOGE_IF(err, "IGraphicBufferProducer::setAutoRefresh(%d) returned %s", | 
 | 1451 |             autoRefresh, strerror(-err)); | 
 | 1452 |     return err; | 
 | 1453 | } | 
 | 1454 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1455 | int Surface::setBuffersDimensions(uint32_t width, uint32_t height) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1456 | { | 
 | 1457 |     ATRACE_CALL(); | 
 | 1458 |     ALOGV("Surface::setBuffersDimensions"); | 
 | 1459 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1460 |     if ((width && !height) || (!width && height)) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1461 |         return BAD_VALUE; | 
 | 1462 |  | 
 | 1463 |     Mutex::Autolock lock(mMutex); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1464 |     if (width != mReqWidth || height != mReqHeight) { | 
 | 1465 |         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; | 
 | 1466 |     } | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1467 |     mReqWidth = width; | 
 | 1468 |     mReqHeight = height; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1469 |     return NO_ERROR; | 
 | 1470 | } | 
 | 1471 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1472 | int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1473 | { | 
 | 1474 |     ATRACE_CALL(); | 
 | 1475 |     ALOGV("Surface::setBuffersUserDimensions"); | 
 | 1476 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1477 |     if ((width && !height) || (!width && height)) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1478 |         return BAD_VALUE; | 
 | 1479 |  | 
 | 1480 |     Mutex::Autolock lock(mMutex); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1481 |     if (width != mUserWidth || height != mUserHeight) { | 
 | 1482 |         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; | 
 | 1483 |     } | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1484 |     mUserWidth = width; | 
 | 1485 |     mUserHeight = height; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1486 |     return NO_ERROR; | 
 | 1487 | } | 
 | 1488 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1489 | int Surface::setBuffersFormat(PixelFormat format) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1490 | { | 
 | 1491 |     ALOGV("Surface::setBuffersFormat"); | 
 | 1492 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1493 |     Mutex::Autolock lock(mMutex); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1494 |     if (format != mReqFormat) { | 
 | 1495 |         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; | 
 | 1496 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1497 |     mReqFormat = format; | 
 | 1498 |     return NO_ERROR; | 
 | 1499 | } | 
 | 1500 |  | 
 | 1501 | int Surface::setScalingMode(int mode) | 
 | 1502 | { | 
 | 1503 |     ATRACE_CALL(); | 
 | 1504 |     ALOGV("Surface::setScalingMode(%d)", mode); | 
 | 1505 |  | 
 | 1506 |     switch (mode) { | 
 | 1507 |         case NATIVE_WINDOW_SCALING_MODE_FREEZE: | 
 | 1508 |         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: | 
 | 1509 |         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: | 
| Robert Carr | c2e7788 | 2015-12-16 18:14:03 -0800 | [diff] [blame] | 1510 |         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1511 |             break; | 
 | 1512 |         default: | 
 | 1513 |             ALOGE("unknown scaling mode: %d", mode); | 
 | 1514 |             return BAD_VALUE; | 
 | 1515 |     } | 
 | 1516 |  | 
 | 1517 |     Mutex::Autolock lock(mMutex); | 
 | 1518 |     mScalingMode = mode; | 
 | 1519 |     return NO_ERROR; | 
 | 1520 | } | 
 | 1521 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1522 | int Surface::setBuffersTransform(uint32_t transform) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1523 | { | 
 | 1524 |     ATRACE_CALL(); | 
 | 1525 |     ALOGV("Surface::setBuffersTransform"); | 
 | 1526 |     Mutex::Autolock lock(mMutex); | 
 | 1527 |     mTransform = transform; | 
 | 1528 |     return NO_ERROR; | 
 | 1529 | } | 
 | 1530 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1531 | int Surface::setBuffersStickyTransform(uint32_t transform) | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 1532 | { | 
 | 1533 |     ATRACE_CALL(); | 
 | 1534 |     ALOGV("Surface::setBuffersStickyTransform"); | 
 | 1535 |     Mutex::Autolock lock(mMutex); | 
 | 1536 |     mStickyTransform = transform; | 
 | 1537 |     return NO_ERROR; | 
 | 1538 | } | 
 | 1539 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1540 | int Surface::setBuffersTimestamp(int64_t timestamp) | 
 | 1541 | { | 
 | 1542 |     ALOGV("Surface::setBuffersTimestamp"); | 
 | 1543 |     Mutex::Autolock lock(mMutex); | 
 | 1544 |     mTimestamp = timestamp; | 
 | 1545 |     return NO_ERROR; | 
 | 1546 | } | 
 | 1547 |  | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 1548 | int Surface::setBuffersDataSpace(Dataspace dataSpace) | 
| Eino-Ville Talvala | 82c6bcc | 2015-02-19 16:10:43 -0800 | [diff] [blame] | 1549 | { | 
 | 1550 |     ALOGV("Surface::setBuffersDataSpace"); | 
 | 1551 |     Mutex::Autolock lock(mMutex); | 
 | 1552 |     mDataSpace = dataSpace; | 
 | 1553 |     return NO_ERROR; | 
 | 1554 | } | 
 | 1555 |  | 
| Courtney Goeltzenleuchter | 9bad0d7 | 2017-12-19 12:34:34 -0700 | [diff] [blame] | 1556 | int Surface::setBuffersSmpte2086Metadata(const android_smpte2086_metadata* metadata) { | 
 | 1557 |     ALOGV("Surface::setBuffersSmpte2086Metadata"); | 
 | 1558 |     Mutex::Autolock lock(mMutex); | 
 | 1559 |     if (metadata) { | 
 | 1560 |         mHdrMetadata.smpte2086 = *metadata; | 
 | 1561 |         mHdrMetadata.validTypes |= HdrMetadata::SMPTE2086; | 
 | 1562 |     } else { | 
 | 1563 |         mHdrMetadata.validTypes &= ~HdrMetadata::SMPTE2086; | 
 | 1564 |     } | 
 | 1565 |     return NO_ERROR; | 
 | 1566 | } | 
 | 1567 |  | 
 | 1568 | int Surface::setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata) { | 
 | 1569 |     ALOGV("Surface::setBuffersCta8613Metadata"); | 
 | 1570 |     Mutex::Autolock lock(mMutex); | 
 | 1571 |     if (metadata) { | 
 | 1572 |         mHdrMetadata.cta8613 = *metadata; | 
 | 1573 |         mHdrMetadata.validTypes |= HdrMetadata::CTA861_3; | 
 | 1574 |     } else { | 
 | 1575 |         mHdrMetadata.validTypes &= ~HdrMetadata::CTA861_3; | 
 | 1576 |     } | 
 | 1577 |     return NO_ERROR; | 
 | 1578 | } | 
 | 1579 |  | 
| Valerie Hau | a82679d | 2018-11-21 09:31:43 -0800 | [diff] [blame] | 1580 | int Surface::setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata) { | 
 | 1581 |     ALOGV("Surface::setBuffersBlobMetadata"); | 
 | 1582 |     Mutex::Autolock lock(mMutex); | 
 | 1583 |     if (size > 0) { | 
 | 1584 |         mHdrMetadata.hdr10plus.assign(metadata, metadata + size); | 
 | 1585 |         mHdrMetadata.validTypes |= HdrMetadata::HDR10PLUS; | 
 | 1586 |     } else { | 
 | 1587 |         mHdrMetadata.validTypes &= ~HdrMetadata::HDR10PLUS; | 
 | 1588 |         mHdrMetadata.hdr10plus.clear(); | 
 | 1589 |     } | 
 | 1590 |     return NO_ERROR; | 
 | 1591 | } | 
 | 1592 |  | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 1593 | Dataspace Surface::getBuffersDataSpace() { | 
| Courtney Goeltzenleuchter | 152279d | 2017-08-14 18:18:30 -0600 | [diff] [blame] | 1594 |     ALOGV("Surface::getBuffersDataSpace"); | 
 | 1595 |     Mutex::Autolock lock(mMutex); | 
 | 1596 |     return mDataSpace; | 
 | 1597 | } | 
 | 1598 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1599 | void Surface::freeAllBuffers() { | 
 | 1600 |     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1601 |         mSlots[i].buffer = nullptr; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1602 |     } | 
 | 1603 | } | 
 | 1604 |  | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 1605 | void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) { | 
 | 1606 |     ATRACE_CALL(); | 
 | 1607 |     ALOGV("Surface::setSurfaceDamage"); | 
 | 1608 |     Mutex::Autolock lock(mMutex); | 
 | 1609 |  | 
| Dan Stoza | c62acbd | 2015-04-21 16:42:49 -0700 | [diff] [blame] | 1610 |     if (mConnectedToCpu || numRects == 0) { | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 1611 |         mDirtyRegion = Region::INVALID_REGION; | 
 | 1612 |         return; | 
 | 1613 |     } | 
 | 1614 |  | 
 | 1615 |     mDirtyRegion.clear(); | 
 | 1616 |     for (size_t r = 0; r < numRects; ++r) { | 
 | 1617 |         // We intentionally flip top and bottom here, since because they're | 
 | 1618 |         // specified with a bottom-left origin, top > bottom, which fails | 
 | 1619 |         // validation in the Region class. We will fix this up when we flip to a | 
 | 1620 |         // top-left origin in queueBuffer. | 
 | 1621 |         Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top); | 
 | 1622 |         mDirtyRegion.orSelf(rect); | 
 | 1623 |     } | 
 | 1624 | } | 
 | 1625 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1626 | // ---------------------------------------------------------------------- | 
 | 1627 | // the lock/unlock APIs must be used from the same thread | 
 | 1628 |  | 
 | 1629 | static status_t copyBlt( | 
 | 1630 |         const sp<GraphicBuffer>& dst, | 
 | 1631 |         const sp<GraphicBuffer>& src, | 
| Francis Hart | 7b09e79 | 2015-01-09 11:10:54 +0200 | [diff] [blame] | 1632 |         const Region& reg, | 
 | 1633 |         int *dstFenceFd) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1634 | { | 
| Dennis Kempin | add458f | 2017-05-17 19:16:31 -0700 | [diff] [blame] | 1635 |     if (dst->getId() == src->getId()) | 
 | 1636 |         return OK; | 
 | 1637 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1638 |     // src and dst with, height and format must be identical. no verification | 
 | 1639 |     // is done here. | 
 | 1640 |     status_t err; | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1641 |     uint8_t* src_bits = nullptr; | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1642 |     err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), | 
 | 1643 |             reinterpret_cast<void**>(&src_bits)); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1644 |     ALOGE_IF(err, "error locking src buffer %s", strerror(-err)); | 
 | 1645 |  | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1646 |     uint8_t* dst_bits = nullptr; | 
| Francis Hart | 7b09e79 | 2015-01-09 11:10:54 +0200 | [diff] [blame] | 1647 |     err = dst->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), | 
 | 1648 |             reinterpret_cast<void**>(&dst_bits), *dstFenceFd); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1649 |     ALOGE_IF(err, "error locking dst buffer %s", strerror(-err)); | 
| Francis Hart | 7b09e79 | 2015-01-09 11:10:54 +0200 | [diff] [blame] | 1650 |     *dstFenceFd = -1; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1651 |  | 
 | 1652 |     Region::const_iterator head(reg.begin()); | 
 | 1653 |     Region::const_iterator tail(reg.end()); | 
 | 1654 |     if (head != tail && src_bits && dst_bits) { | 
 | 1655 |         const size_t bpp = bytesPerPixel(src->format); | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1656 |         const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp; | 
 | 1657 |         const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1658 |  | 
 | 1659 |         while (head != tail) { | 
 | 1660 |             const Rect& r(*head++); | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1661 |             int32_t h = r.height(); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1662 |             if (h <= 0) continue; | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1663 |             size_t size = static_cast<uint32_t>(r.width()) * bpp; | 
 | 1664 |             uint8_t const * s = src_bits + | 
 | 1665 |                     static_cast<uint32_t>(r.left + src->stride * r.top) * bpp; | 
 | 1666 |             uint8_t       * d = dst_bits + | 
 | 1667 |                     static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1668 |             if (dbpr==sbpr && size==sbpr) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1669 |                 size *= static_cast<size_t>(h); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1670 |                 h = 1; | 
 | 1671 |             } | 
 | 1672 |             do { | 
 | 1673 |                 memcpy(d, s, size); | 
 | 1674 |                 d += dbpr; | 
 | 1675 |                 s += sbpr; | 
 | 1676 |             } while (--h > 0); | 
 | 1677 |         } | 
 | 1678 |     } | 
 | 1679 |  | 
 | 1680 |     if (src_bits) | 
 | 1681 |         src->unlock(); | 
 | 1682 |  | 
 | 1683 |     if (dst_bits) | 
| Francis Hart | 7b09e79 | 2015-01-09 11:10:54 +0200 | [diff] [blame] | 1684 |         dst->unlockAsync(dstFenceFd); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1685 |  | 
 | 1686 |     return err; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1687 | } | 
 | 1688 |  | 
| Mathias Agopian | a138f89 | 2010-05-21 17:24:35 -0700 | [diff] [blame] | 1689 | // ---------------------------------------------------------------------------- | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1690 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1691 | status_t Surface::lock( | 
 | 1692 |         ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds) | 
 | 1693 | { | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1694 |     if (mLockedBuffer != nullptr) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1695 |         ALOGE("Surface::lock failed, already locked"); | 
 | 1696 |         return INVALID_OPERATION; | 
 | 1697 |     } | 
 | 1698 |  | 
 | 1699 |     if (!mConnectedToCpu) { | 
 | 1700 |         int err = Surface::connect(NATIVE_WINDOW_API_CPU); | 
 | 1701 |         if (err) { | 
 | 1702 |             return err; | 
 | 1703 |         } | 
 | 1704 |         // we're intending to do software rendering from this point | 
 | 1705 |         setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); | 
 | 1706 |     } | 
 | 1707 |  | 
 | 1708 |     ANativeWindowBuffer* out; | 
 | 1709 |     int fenceFd = -1; | 
 | 1710 |     status_t err = dequeueBuffer(&out, &fenceFd); | 
 | 1711 |     ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err)); | 
 | 1712 |     if (err == NO_ERROR) { | 
 | 1713 |         sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out)); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1714 |         const Rect bounds(backBuffer->width, backBuffer->height); | 
 | 1715 |  | 
 | 1716 |         Region newDirtyRegion; | 
 | 1717 |         if (inOutDirtyBounds) { | 
 | 1718 |             newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds)); | 
 | 1719 |             newDirtyRegion.andSelf(bounds); | 
 | 1720 |         } else { | 
 | 1721 |             newDirtyRegion.set(bounds); | 
 | 1722 |         } | 
 | 1723 |  | 
 | 1724 |         // figure out if we can copy the frontbuffer back | 
 | 1725 |         const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1726 |         const bool canCopyBack = (frontBuffer != nullptr && | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1727 |                 backBuffer->width  == frontBuffer->width && | 
 | 1728 |                 backBuffer->height == frontBuffer->height && | 
 | 1729 |                 backBuffer->format == frontBuffer->format); | 
 | 1730 |  | 
 | 1731 |         if (canCopyBack) { | 
 | 1732 |             // copy the area that is invalid and not repainted this round | 
 | 1733 |             const Region copyback(mDirtyRegion.subtract(newDirtyRegion)); | 
| Francis Hart | dc10f84 | 2014-12-01 16:04:49 +0200 | [diff] [blame] | 1734 |             if (!copyback.isEmpty()) { | 
| Francis Hart | 7b09e79 | 2015-01-09 11:10:54 +0200 | [diff] [blame] | 1735 |                 copyBlt(backBuffer, frontBuffer, copyback, &fenceFd); | 
| Francis Hart | dc10f84 | 2014-12-01 16:04:49 +0200 | [diff] [blame] | 1736 |             } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1737 |         } else { | 
 | 1738 |             // if we can't copy-back anything, modify the user's dirty | 
 | 1739 |             // region to make sure they redraw the whole buffer | 
 | 1740 |             newDirtyRegion.set(bounds); | 
 | 1741 |             mDirtyRegion.clear(); | 
 | 1742 |             Mutex::Autolock lock(mMutex); | 
 | 1743 |             for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) { | 
 | 1744 |                 mSlots[i].dirtyRegion.clear(); | 
 | 1745 |             } | 
 | 1746 |         } | 
 | 1747 |  | 
 | 1748 |  | 
 | 1749 |         { // scope for the lock | 
 | 1750 |             Mutex::Autolock lock(mMutex); | 
 | 1751 |             int backBufferSlot(getSlotFromBufferLocked(backBuffer.get())); | 
 | 1752 |             if (backBufferSlot >= 0) { | 
 | 1753 |                 Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion); | 
 | 1754 |                 mDirtyRegion.subtract(dirtyRegion); | 
 | 1755 |                 dirtyRegion = newDirtyRegion; | 
 | 1756 |             } | 
 | 1757 |         } | 
 | 1758 |  | 
 | 1759 |         mDirtyRegion.orSelf(newDirtyRegion); | 
 | 1760 |         if (inOutDirtyBounds) { | 
 | 1761 |             *inOutDirtyBounds = newDirtyRegion.getBounds(); | 
 | 1762 |         } | 
 | 1763 |  | 
 | 1764 |         void* vaddr; | 
| Francis Hart | 8f39601 | 2014-04-01 15:30:53 +0300 | [diff] [blame] | 1765 |         status_t res = backBuffer->lockAsync( | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1766 |                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, | 
| Francis Hart | 8f39601 | 2014-04-01 15:30:53 +0300 | [diff] [blame] | 1767 |                 newDirtyRegion.bounds(), &vaddr, fenceFd); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1768 |  | 
 | 1769 |         ALOGW_IF(res, "failed locking buffer (handle = %p)", | 
 | 1770 |                 backBuffer->handle); | 
 | 1771 |  | 
 | 1772 |         if (res != 0) { | 
 | 1773 |             err = INVALID_OPERATION; | 
 | 1774 |         } else { | 
 | 1775 |             mLockedBuffer = backBuffer; | 
 | 1776 |             outBuffer->width  = backBuffer->width; | 
 | 1777 |             outBuffer->height = backBuffer->height; | 
 | 1778 |             outBuffer->stride = backBuffer->stride; | 
 | 1779 |             outBuffer->format = backBuffer->format; | 
 | 1780 |             outBuffer->bits   = vaddr; | 
 | 1781 |         } | 
 | 1782 |     } | 
 | 1783 |     return err; | 
 | 1784 | } | 
 | 1785 |  | 
 | 1786 | status_t Surface::unlockAndPost() | 
 | 1787 | { | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1788 |     if (mLockedBuffer == nullptr) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1789 |         ALOGE("Surface::unlockAndPost failed, no locked buffer"); | 
 | 1790 |         return INVALID_OPERATION; | 
 | 1791 |     } | 
 | 1792 |  | 
| Francis Hart | 8f39601 | 2014-04-01 15:30:53 +0300 | [diff] [blame] | 1793 |     int fd = -1; | 
 | 1794 |     status_t err = mLockedBuffer->unlockAsync(&fd); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1795 |     ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle); | 
 | 1796 |  | 
| Francis Hart | 8f39601 | 2014-04-01 15:30:53 +0300 | [diff] [blame] | 1797 |     err = queueBuffer(mLockedBuffer.get(), fd); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1798 |     ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)", | 
 | 1799 |             mLockedBuffer->handle, strerror(-err)); | 
 | 1800 |  | 
 | 1801 |     mPostedBuffer = mLockedBuffer; | 
| Yi Kong | 48a619f | 2018-06-05 16:34:59 -0700 | [diff] [blame] | 1802 |     mLockedBuffer = nullptr; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1803 |     return err; | 
 | 1804 | } | 
 | 1805 |  | 
| Robert Carr | 9f31e29 | 2016-04-11 11:15:32 -0700 | [diff] [blame] | 1806 | bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) { | 
 | 1807 |     Mutex::Autolock lock(mMutex); | 
| Pablo Ceballos | bc8c192 | 2016-07-01 14:15:41 -0700 | [diff] [blame] | 1808 |     if (mNextFrameNumber > lastFrame) { | 
| Robert Carr | 9f31e29 | 2016-04-11 11:15:32 -0700 | [diff] [blame] | 1809 |       return true; | 
 | 1810 |     } | 
 | 1811 |     return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK; | 
 | 1812 | } | 
 | 1813 |  | 
| Pablo Ceballos | 8e3e92b | 2016-06-27 17:56:53 -0700 | [diff] [blame] | 1814 | status_t Surface::getUniqueId(uint64_t* outId) const { | 
 | 1815 |     Mutex::Autolock lock(mMutex); | 
 | 1816 |     return mGraphicBufferProducer->getUniqueId(outId); | 
 | 1817 | } | 
 | 1818 |  | 
| Chia-I Wu | e2786ea | 2017-08-07 10:36:08 -0700 | [diff] [blame] | 1819 | int Surface::getConsumerUsage(uint64_t* outUsage) const { | 
 | 1820 |     Mutex::Autolock lock(mMutex); | 
 | 1821 |     return mGraphicBufferProducer->getConsumerUsage(outUsage); | 
 | 1822 | } | 
 | 1823 |  | 
| Dan Stoza | 932f008 | 2017-05-31 13:50:16 -0700 | [diff] [blame] | 1824 | nsecs_t Surface::getLastDequeueStartTime() const { | 
 | 1825 |     Mutex::Autolock lock(mMutex); | 
 | 1826 |     return mLastDequeueStartTime; | 
 | 1827 | } | 
 | 1828 |  | 
| Yin-Chia Yeh | e572fd7 | 2017-03-28 19:07:39 -0700 | [diff] [blame] | 1829 | status_t Surface::getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out) { | 
 | 1830 |     if (out == nullptr) { | 
 | 1831 |         ALOGE("%s: out must not be null!", __FUNCTION__); | 
 | 1832 |         return BAD_VALUE; | 
 | 1833 |     } | 
 | 1834 |  | 
 | 1835 |     Mutex::Autolock lock(mMutex); | 
 | 1836 |     *out = mRemovedBuffers; | 
 | 1837 |     mRemovedBuffers.clear(); | 
 | 1838 |     return OK; | 
 | 1839 | } | 
 | 1840 |  | 
| Chavi Weingarten | 40482ff | 2017-11-30 01:51:40 +0000 | [diff] [blame] | 1841 | status_t Surface::attachAndQueueBuffer(Surface* surface, sp<GraphicBuffer> buffer) { | 
 | 1842 |     if (buffer == nullptr) { | 
 | 1843 |         return BAD_VALUE; | 
 | 1844 |     } | 
 | 1845 |     int err = static_cast<ANativeWindow*>(surface)->perform(surface, NATIVE_WINDOW_API_CONNECT, | 
 | 1846 |                                                             NATIVE_WINDOW_API_CPU); | 
 | 1847 |     if (err != OK) { | 
 | 1848 |         return err; | 
 | 1849 |     } | 
 | 1850 |     err = surface->attachBuffer(buffer->getNativeBuffer()); | 
 | 1851 |     if (err != OK) { | 
 | 1852 |         return err; | 
 | 1853 |     } | 
 | 1854 |     err = static_cast<ANativeWindow*>(surface)->queueBuffer(surface, buffer->getNativeBuffer(), -1); | 
 | 1855 |     if (err != OK) { | 
 | 1856 |         return err; | 
 | 1857 |     } | 
 | 1858 |     err = surface->disconnect(NATIVE_WINDOW_API_CPU); | 
 | 1859 |     return err; | 
 | 1860 | } | 
 | 1861 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1862 | }; // namespace android |