| 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 | b0e76f4 | 2012-03-23 14:15:44 -0700 | [diff] [blame] | 21 | #include <android/native_window.h> | 
 | 22 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 23 | #include <binder/Parcel.h> | 
 | 24 |  | 
| Mathias Agopian | 9cce325 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 25 | #include <utils/Log.h> | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 26 | #include <utils/Trace.h> | 
| Rachad | 7cb0d39 | 2014-07-29 17:53:53 -0700 | [diff] [blame] | 27 | #include <utils/NativeHandle.h> | 
| Mathias Agopian | 9cce325 | 2010-02-09 17:46:37 -0800 | [diff] [blame] | 28 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 29 | #include <ui/Fence.h> | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 30 | #include <ui/Region.h> | 
| Mathias Agopian | a67932f | 2011-04-20 14:20:59 -0700 | [diff] [blame] | 31 |  | 
| Dan Stoza | f0eaf25 | 2014-03-21 13:05:51 -0700 | [diff] [blame] | 32 | #include <gui/IProducerListener.h> | 
| Mathias Agopian | 90ac799 | 2012-02-25 18:48:35 -0800 | [diff] [blame] | 33 | #include <gui/ISurfaceComposer.h> | 
| Mathias Agopian | 90ac799 | 2012-02-25 18:48:35 -0800 | [diff] [blame] | 34 | #include <gui/SurfaceComposerClient.h> | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 35 | #include <gui/GLConsumer.h> | 
 | 36 | #include <gui/Surface.h> | 
 | 37 |  | 
 | 38 | #include <private/gui/ComposerService.h> | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 39 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 40 | namespace android { | 
 | 41 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 42 | Surface::Surface( | 
| Mathias Agopian | 595264f | 2013-07-16 22:56:09 -0700 | [diff] [blame] | 43 |         const sp<IGraphicBufferProducer>& bufferProducer, | 
 | 44 |         bool controlledByApp) | 
| Dan Stoza | 812ed06 | 2015-06-02 15:45:22 -0700 | [diff] [blame] | 45 |     : mGraphicBufferProducer(bufferProducer), | 
| Pablo Ceballos | 60d6922 | 2015-08-07 14:47:20 -0700 | [diff] [blame] | 46 |       mCrop(Rect::EMPTY_RECT), | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 47 |       mGenerationNumber(0), | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 48 |       mSharedBufferMode(false), | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 49 |       mAutoRefresh(false), | 
 | 50 |       mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), | 
| Pablo Ceballos | bc8c192 | 2016-07-01 14:15:41 -0700 | [diff] [blame] | 51 |       mSharedBufferHasBeenQueued(false), | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 52 |       mNextFrameNumber(1), | 
 | 53 |       mQueriedSupportedTimestamps(false), | 
 | 54 |       mFrameTimestampsSupportsPresent(false), | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 55 |       mFrameTimestampsSupportsRetire(false), | 
 | 56 |       mEnableFrameTimestamps(false) | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 57 | { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 58 |     // Initialize the ANativeWindow function pointers. | 
 | 59 |     ANativeWindow::setSwapInterval  = hook_setSwapInterval; | 
 | 60 |     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer; | 
 | 61 |     ANativeWindow::cancelBuffer     = hook_cancelBuffer; | 
 | 62 |     ANativeWindow::queueBuffer      = hook_queueBuffer; | 
 | 63 |     ANativeWindow::query            = hook_query; | 
 | 64 |     ANativeWindow::perform          = hook_perform; | 
 | 65 |  | 
 | 66 |     ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED; | 
 | 67 |     ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED; | 
 | 68 |     ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED; | 
 | 69 |     ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED; | 
 | 70 |  | 
 | 71 |     const_cast<int&>(ANativeWindow::minSwapInterval) = 0; | 
 | 72 |     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; | 
 | 73 |  | 
 | 74 |     mReqWidth = 0; | 
 | 75 |     mReqHeight = 0; | 
 | 76 |     mReqFormat = 0; | 
 | 77 |     mReqUsage = 0; | 
 | 78 |     mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO; | 
| Eino-Ville Talvala | 82c6bcc | 2015-02-19 16:10:43 -0800 | [diff] [blame] | 79 |     mDataSpace = HAL_DATASPACE_UNKNOWN; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 80 |     mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; | 
 | 81 |     mTransform = 0; | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 82 |     mStickyTransform = 0; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 83 |     mDefaultWidth = 0; | 
 | 84 |     mDefaultHeight = 0; | 
 | 85 |     mUserWidth = 0; | 
 | 86 |     mUserHeight = 0; | 
 | 87 |     mTransformHint = 0; | 
 | 88 |     mConsumerRunningBehind = false; | 
 | 89 |     mConnectedToCpu = false; | 
| Eino-Ville Talvala | 7895e90 | 2013-08-21 11:53:37 -0700 | [diff] [blame] | 90 |     mProducerControlledByApp = controlledByApp; | 
| Mathias Agopian | 7cdd786 | 2013-07-18 22:10:56 -0700 | [diff] [blame] | 91 |     mSwapIntervalZero = false; | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 92 | } | 
 | 93 |  | 
| Mathias Agopian | 35ffa6a | 2013-03-12 18:45:09 -0700 | [diff] [blame] | 94 | Surface::~Surface() { | 
 | 95 |     if (mConnectedToCpu) { | 
 | 96 |         Surface::disconnect(NATIVE_WINDOW_API_CPU); | 
 | 97 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 98 | } | 
 | 99 |  | 
 | 100 | sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const { | 
 | 101 |     return mGraphicBufferProducer; | 
 | 102 | } | 
 | 103 |  | 
| Wonsik Kim | 0ee14ca | 2014-03-17 17:46:53 +0900 | [diff] [blame] | 104 | void Surface::setSidebandStream(const sp<NativeHandle>& stream) { | 
 | 105 |     mGraphicBufferProducer->setSidebandStream(stream); | 
 | 106 | } | 
 | 107 |  | 
| Dan Stoza | 29a3e90 | 2014-06-20 13:13:57 -0700 | [diff] [blame] | 108 | void Surface::allocateBuffers() { | 
 | 109 |     uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth; | 
 | 110 |     uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight; | 
| Pablo Ceballos | 567dbbb | 2015-08-26 18:59:08 -0700 | [diff] [blame] | 111 |     mGraphicBufferProducer->allocateBuffers(reqWidth, reqHeight, | 
 | 112 |             mReqFormat, mReqUsage); | 
| Dan Stoza | 29a3e90 | 2014-06-20 13:13:57 -0700 | [diff] [blame] | 113 | } | 
 | 114 |  | 
| Dan Stoza | 812ed06 | 2015-06-02 15:45:22 -0700 | [diff] [blame] | 115 | status_t Surface::setGenerationNumber(uint32_t generation) { | 
 | 116 |     status_t result = mGraphicBufferProducer->setGenerationNumber(generation); | 
 | 117 |     if (result == NO_ERROR) { | 
 | 118 |         mGenerationNumber = generation; | 
 | 119 |     } | 
 | 120 |     return result; | 
 | 121 | } | 
 | 122 |  | 
| Dan Stoza | 7dde599 | 2015-05-22 09:51:44 -0700 | [diff] [blame] | 123 | uint64_t Surface::getNextFrameNumber() const { | 
| Pablo Ceballos | bc8c192 | 2016-07-01 14:15:41 -0700 | [diff] [blame] | 124 |     Mutex::Autolock lock(mMutex); | 
 | 125 |     return mNextFrameNumber; | 
| Dan Stoza | 7dde599 | 2015-05-22 09:51:44 -0700 | [diff] [blame] | 126 | } | 
 | 127 |  | 
| Dan Stoza | c6f30bd | 2015-06-08 09:32:50 -0700 | [diff] [blame] | 128 | String8 Surface::getConsumerName() const { | 
 | 129 |     return mGraphicBufferProducer->getConsumerName(); | 
 | 130 | } | 
 | 131 |  | 
| Dan Stoza | 127fc63 | 2015-06-30 13:43:32 -0700 | [diff] [blame] | 132 | status_t Surface::setDequeueTimeout(nsecs_t timeout) { | 
 | 133 |     return mGraphicBufferProducer->setDequeueTimeout(timeout); | 
 | 134 | } | 
 | 135 |  | 
| Dan Stoza | 50101d0 | 2016-04-07 16:53:23 -0700 | [diff] [blame] | 136 | status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, | 
| John Reck | 1a61da5 | 2016-04-28 13:18:15 -0700 | [diff] [blame] | 137 |         sp<Fence>* outFence, float outTransformMatrix[16]) { | 
 | 138 |     return mGraphicBufferProducer->getLastQueuedBuffer(outBuffer, outFence, | 
 | 139 |             outTransformMatrix); | 
| Dan Stoza | 50101d0 | 2016-04-07 16:53:23 -0700 | [diff] [blame] | 140 | } | 
 | 141 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 142 | void Surface::enableFrameTimestamps(bool enable) { | 
 | 143 |     Mutex::Autolock lock(mMutex); | 
 | 144 |     mEnableFrameTimestamps = enable; | 
 | 145 | } | 
 | 146 |  | 
| Brian Anderson | 3d4039d | 2016-09-23 16:31:30 -0700 | [diff] [blame] | 147 | static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) { | 
 | 148 |     if (dst != nullptr) { | 
 | 149 |         *dst = Fence::isValidTimestamp(src) ? src : 0; | 
 | 150 |     } | 
 | 151 | } | 
 | 152 |  | 
 | 153 | static void getFrameTimestampFence(nsecs_t *dst, const std::shared_ptr<FenceTime>& src) { | 
 | 154 |     if (dst != nullptr) { | 
 | 155 |         nsecs_t signalTime = src->getSignalTime(); | 
 | 156 |         *dst = Fence::isValidTimestamp(signalTime) ? signalTime : 0; | 
 | 157 |     } | 
 | 158 | } | 
 | 159 |  | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 160 | status_t Surface::getFrameTimestamps(uint64_t frameNumber, | 
| Brian Anderson | dbd0ea8 | 2016-07-22 09:38:59 -0700 | [diff] [blame] | 161 |         nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime, | 
 | 162 |         nsecs_t* outRefreshStartTime, nsecs_t* outGlCompositionDoneTime, | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 163 |         nsecs_t* outDisplayPresentTime, nsecs_t* outDisplayRetireTime, | 
 | 164 |         nsecs_t* outReleaseTime) { | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 165 |     ATRACE_CALL(); | 
 | 166 |  | 
| Brian Anderson | 3890c39 | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 167 |     Mutex::Autolock lock(mMutex); | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 168 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 169 |     if (!mEnableFrameTimestamps) { | 
 | 170 |         return INVALID_OPERATION; | 
 | 171 |     } | 
 | 172 |  | 
| Brian Anderson | 3890c39 | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 173 |     // Verify the requested timestamps are supported. | 
 | 174 |     querySupportedTimestampsLocked(); | 
 | 175 |     if (outDisplayPresentTime != nullptr && !mFrameTimestampsSupportsPresent) { | 
 | 176 |         return BAD_VALUE; | 
 | 177 |     } | 
 | 178 |     if (outDisplayRetireTime != nullptr && !mFrameTimestampsSupportsRetire) { | 
 | 179 |         return BAD_VALUE; | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 180 |     } | 
 | 181 |  | 
| Brian Anderson | 3890c39 | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 182 |     FrameEvents* events = mFrameEventHistory.getFrame(frameNumber); | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 183 |  | 
| Brian Anderson | 3890c39 | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 184 |     // Update our cache of events if the requested events are not available. | 
 | 185 |     if (events == nullptr || | 
 | 186 |         (outRequestedPresentTime && !events->hasRequestedPresentInfo()) || | 
 | 187 |         (outAcquireTime && !events->hasAcquireInfo()) || | 
 | 188 |         (outRefreshStartTime && !events->hasFirstRefreshStartInfo()) || | 
 | 189 |         (outGlCompositionDoneTime && !events->hasGpuCompositionDoneInfo()) || | 
 | 190 |         (outDisplayPresentTime && !events->hasDisplayPresentInfo()) || | 
 | 191 |         (outDisplayRetireTime && !events->hasDisplayRetireInfo()) || | 
 | 192 |         (outReleaseTime && !events->hasReleaseInfo())) { | 
 | 193 |             FrameEventHistoryDelta delta; | 
 | 194 |             mGraphicBufferProducer->getFrameTimestamps(&delta); | 
 | 195 |             mFrameEventHistory.applyDelta(delta); | 
 | 196 |             events = mFrameEventHistory.getFrame(frameNumber); | 
 | 197 |     } | 
 | 198 |  | 
 | 199 |     // A record for the requested frame does not exist. | 
 | 200 |     if (events == nullptr) { | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 201 |         return NAME_NOT_FOUND; | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 202 |     } | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 203 |  | 
| Brian Anderson | 3d4039d | 2016-09-23 16:31:30 -0700 | [diff] [blame] | 204 |     getFrameTimestamp(outRequestedPresentTime, events->requestedPresentTime); | 
 | 205 |     getFrameTimestamp(outRefreshStartTime, events->firstRefreshStartTime); | 
| Brian Anderson | 3890c39 | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 206 |  | 
| Brian Anderson | 3d4039d | 2016-09-23 16:31:30 -0700 | [diff] [blame] | 207 |     getFrameTimestampFence(outAcquireTime, events->acquireFence); | 
 | 208 |     getFrameTimestampFence( | 
 | 209 |             outGlCompositionDoneTime, events->gpuCompositionDoneFence); | 
 | 210 |     getFrameTimestampFence( | 
 | 211 |             outDisplayPresentTime, events->displayPresentFence); | 
 | 212 |     getFrameTimestampFence(outDisplayRetireTime, events->displayRetireFence); | 
 | 213 |     getFrameTimestampFence(outReleaseTime, events->releaseFence); | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 214 |  | 
 | 215 |     return NO_ERROR; | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 216 | } | 
 | 217 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 218 | int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) { | 
 | 219 |     Surface* c = getSelf(window); | 
 | 220 |     return c->setSwapInterval(interval); | 
 | 221 | } | 
 | 222 |  | 
 | 223 | int Surface::hook_dequeueBuffer(ANativeWindow* window, | 
 | 224 |         ANativeWindowBuffer** buffer, int* fenceFd) { | 
 | 225 |     Surface* c = getSelf(window); | 
 | 226 |     return c->dequeueBuffer(buffer, fenceFd); | 
 | 227 | } | 
 | 228 |  | 
 | 229 | int Surface::hook_cancelBuffer(ANativeWindow* window, | 
 | 230 |         ANativeWindowBuffer* buffer, int fenceFd) { | 
 | 231 |     Surface* c = getSelf(window); | 
 | 232 |     return c->cancelBuffer(buffer, fenceFd); | 
 | 233 | } | 
 | 234 |  | 
 | 235 | int Surface::hook_queueBuffer(ANativeWindow* window, | 
 | 236 |         ANativeWindowBuffer* buffer, int fenceFd) { | 
 | 237 |     Surface* c = getSelf(window); | 
 | 238 |     return c->queueBuffer(buffer, fenceFd); | 
 | 239 | } | 
 | 240 |  | 
 | 241 | int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, | 
 | 242 |         ANativeWindowBuffer** buffer) { | 
 | 243 |     Surface* c = getSelf(window); | 
 | 244 |     ANativeWindowBuffer* buf; | 
 | 245 |     int fenceFd = -1; | 
 | 246 |     int result = c->dequeueBuffer(&buf, &fenceFd); | 
| Mike Stroyan | 87709c9 | 2016-06-03 12:43:26 -0600 | [diff] [blame] | 247 |     if (result != OK) { | 
 | 248 |         return result; | 
 | 249 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 250 |     sp<Fence> fence(new Fence(fenceFd)); | 
| Mathias Agopian | ea74d3b | 2013-05-16 18:03:22 -0700 | [diff] [blame] | 251 |     int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED"); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 252 |     if (waitResult != OK) { | 
 | 253 |         ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d", | 
 | 254 |                 waitResult); | 
 | 255 |         c->cancelBuffer(buf, -1); | 
 | 256 |         return waitResult; | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 257 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 258 |     *buffer = buf; | 
 | 259 |     return result; | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 260 | } | 
 | 261 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 262 | int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window, | 
 | 263 |         ANativeWindowBuffer* buffer) { | 
 | 264 |     Surface* c = getSelf(window); | 
 | 265 |     return c->cancelBuffer(buffer, -1); | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 266 | } | 
 | 267 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 268 | int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window, | 
 | 269 |         ANativeWindowBuffer* buffer) { | 
 | 270 |     Surface* c = getSelf(window); | 
 | 271 |     return c->lockBuffer_DEPRECATED(buffer); | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 272 | } | 
 | 273 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 274 | int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window, | 
 | 275 |         ANativeWindowBuffer* buffer) { | 
 | 276 |     Surface* c = getSelf(window); | 
 | 277 |     return c->queueBuffer(buffer, -1); | 
| Jamie Gennis | f15a83f | 2012-05-10 20:43:55 -0700 | [diff] [blame] | 278 | } | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 279 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 280 | int Surface::hook_query(const ANativeWindow* window, | 
 | 281 |                                 int what, int* value) { | 
 | 282 |     const Surface* c = getSelf(window); | 
 | 283 |     return c->query(what, value); | 
 | 284 | } | 
 | 285 |  | 
 | 286 | int Surface::hook_perform(ANativeWindow* window, int operation, ...) { | 
 | 287 |     va_list args; | 
 | 288 |     va_start(args, operation); | 
 | 289 |     Surface* c = getSelf(window); | 
| Haixia Shi | d89c2bb | 2015-09-14 11:02:18 -0700 | [diff] [blame] | 290 |     int result = c->perform(operation, args); | 
 | 291 |     va_end(args); | 
 | 292 |     return result; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 293 | } | 
 | 294 |  | 
 | 295 | int Surface::setSwapInterval(int interval) { | 
 | 296 |     ATRACE_CALL(); | 
 | 297 |     // EGL specification states: | 
 | 298 |     //  interval is silently clamped to minimum and maximum implementation | 
 | 299 |     //  dependent values before being stored. | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 300 |  | 
 | 301 |     if (interval < minSwapInterval) | 
 | 302 |         interval = minSwapInterval; | 
 | 303 |  | 
 | 304 |     if (interval > maxSwapInterval) | 
 | 305 |         interval = maxSwapInterval; | 
 | 306 |  | 
| Mathias Agopian | 7cdd786 | 2013-07-18 22:10:56 -0700 | [diff] [blame] | 307 |     mSwapIntervalZero = (interval == 0); | 
| Pablo Ceballos | 567dbbb | 2015-08-26 18:59:08 -0700 | [diff] [blame] | 308 |     mGraphicBufferProducer->setAsyncMode(mSwapIntervalZero); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 309 |  | 
| Mathias Agopian | 7cdd786 | 2013-07-18 22:10:56 -0700 | [diff] [blame] | 310 |     return NO_ERROR; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 311 | } | 
 | 312 |  | 
| Mathias Agopian | ba93b3f | 2013-08-01 15:48:40 -0700 | [diff] [blame] | 313 | int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 314 |     ATRACE_CALL(); | 
 | 315 |     ALOGV("Surface::dequeueBuffer"); | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 316 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 317 |     uint32_t reqWidth; | 
 | 318 |     uint32_t reqHeight; | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 319 |     PixelFormat reqFormat; | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 320 |     uint32_t reqUsage; | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 321 |     bool enableFrameTimestamps; | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 322 |  | 
 | 323 |     { | 
 | 324 |         Mutex::Autolock lock(mMutex); | 
 | 325 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 326 |         reqWidth = mReqWidth ? mReqWidth : mUserWidth; | 
 | 327 |         reqHeight = mReqHeight ? mReqHeight : mUserHeight; | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 328 |  | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 329 |         reqFormat = mReqFormat; | 
 | 330 |         reqUsage = mReqUsage; | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 331 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 332 |         enableFrameTimestamps = mEnableFrameTimestamps; | 
 | 333 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 334 |         if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot != | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 335 |                 BufferItem::INVALID_BUFFER_SLOT) { | 
 | 336 |             sp<GraphicBuffer>& gbuf(mSlots[mSharedBufferSlot].buffer); | 
 | 337 |             if (gbuf != NULL) { | 
 | 338 |                 *buffer = gbuf.get(); | 
 | 339 |                 *fenceFd = -1; | 
 | 340 |                 return OK; | 
 | 341 |             } | 
 | 342 |         } | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 343 |     } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer | 
 | 344 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 345 |     int buf = -1; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 346 |     sp<Fence> fence; | 
| Dan Stoza | 70ccba5 | 2016-07-01 14:00:40 -0700 | [diff] [blame] | 347 |     nsecs_t now = systemTime(); | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 348 |  | 
 | 349 |     FrameEventHistoryDelta frameTimestamps; | 
 | 350 |     FrameEventHistoryDelta* frameTimestampsOrNull = | 
 | 351 |             enableFrameTimestamps ? &frameTimestamps : nullptr; | 
 | 352 |  | 
| Pablo Ceballos | 567dbbb | 2015-08-26 18:59:08 -0700 | [diff] [blame] | 353 |     status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 354 |             reqWidth, reqHeight, reqFormat, reqUsage, frameTimestampsOrNull); | 
| Dan Stoza | 70ccba5 | 2016-07-01 14:00:40 -0700 | [diff] [blame] | 355 |     mLastDequeueDuration = systemTime() - now; | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 356 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 357 |     if (result < 0) { | 
| Pablo Ceballos | 567dbbb | 2015-08-26 18:59:08 -0700 | [diff] [blame] | 358 |         ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer" | 
 | 359 |                 "(%d, %d, %d, %d) failed: %d", reqWidth, reqHeight, reqFormat, | 
 | 360 |                 reqUsage, result); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 361 |         return result; | 
| Mathias Agopian | 62185b7 | 2009-04-16 16:19:50 -0700 | [diff] [blame] | 362 |     } | 
| Igor Murashkin | 0f1889e | 2014-02-28 18:44:21 -0800 | [diff] [blame] | 363 |  | 
 | 364 |     Mutex::Autolock lock(mMutex); | 
 | 365 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 366 |     sp<GraphicBuffer>& gbuf(mSlots[buf].buffer); | 
| Mathias Agopian | ba93b3f | 2013-08-01 15:48:40 -0700 | [diff] [blame] | 367 |  | 
 | 368 |     // this should never happen | 
 | 369 |     ALOGE_IF(fence == NULL, "Surface::dequeueBuffer: received null Fence! buf=%d", buf); | 
 | 370 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 371 |     if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) { | 
 | 372 |         freeAllBuffers(); | 
| Mathias Agopian | 579b3f8 | 2010-06-08 19:54:15 -0700 | [diff] [blame] | 373 |     } | 
| Ted Bonkenburg | bd050ab | 2011-07-15 15:10:10 -0700 | [diff] [blame] | 374 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 375 |     if (enableFrameTimestamps) { | 
 | 376 |          mFrameEventHistory.applyDelta(frameTimestamps); | 
 | 377 |     } | 
 | 378 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 379 |     if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) { | 
 | 380 |         result = mGraphicBufferProducer->requestBuffer(buf, &gbuf); | 
 | 381 |         if (result != NO_ERROR) { | 
| Mathias Agopian | ba93b3f | 2013-08-01 15:48:40 -0700 | [diff] [blame] | 382 |             ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result); | 
| Jesse Hall | 9f5a1b6 | 2014-10-02 11:09:03 -0700 | [diff] [blame] | 383 |             mGraphicBufferProducer->cancelBuffer(buf, fence); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 384 |             return result; | 
 | 385 |         } | 
 | 386 |     } | 
| Mathias Agopian | 579b3f8 | 2010-06-08 19:54:15 -0700 | [diff] [blame] | 387 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 388 |     if (fence->isValid()) { | 
 | 389 |         *fenceFd = fence->dup(); | 
 | 390 |         if (*fenceFd == -1) { | 
 | 391 |             ALOGE("dequeueBuffer: error duping fence: %d", errno); | 
 | 392 |             // dup() should never fail; something is badly wrong. Soldier on | 
 | 393 |             // and hope for the best; the worst that should happen is some | 
 | 394 |             // visible corruption that lasts until the next frame. | 
 | 395 |         } | 
| Ted Bonkenburg | e5d6eb8 | 2011-08-09 22:38:41 -0700 | [diff] [blame] | 396 |     } else { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 397 |         *fenceFd = -1; | 
| Mathias Agopian | a0c30e9 | 2010-06-04 18:26:32 -0700 | [diff] [blame] | 398 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 399 |  | 
 | 400 |     *buffer = gbuf.get(); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 401 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 402 |     if (mSharedBufferMode && mAutoRefresh) { | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 403 |         mSharedBufferSlot = buf; | 
 | 404 |         mSharedBufferHasBeenQueued = false; | 
 | 405 |     } else if (mSharedBufferSlot == buf) { | 
 | 406 |         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; | 
 | 407 |         mSharedBufferHasBeenQueued = false; | 
 | 408 |     } | 
 | 409 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 410 |     return OK; | 
| Jamie Gennis | aca4e22 | 2010-07-15 17:29:15 -0700 | [diff] [blame] | 411 | } | 
 | 412 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 413 | int Surface::cancelBuffer(android_native_buffer_t* buffer, | 
 | 414 |         int fenceFd) { | 
 | 415 |     ATRACE_CALL(); | 
 | 416 |     ALOGV("Surface::cancelBuffer"); | 
 | 417 |     Mutex::Autolock lock(mMutex); | 
 | 418 |     int i = getSlotFromBufferLocked(buffer); | 
 | 419 |     if (i < 0) { | 
| Taiju Tsuiki | 4d0cd3f | 2015-04-30 22:15:33 +0900 | [diff] [blame] | 420 |         if (fenceFd >= 0) { | 
 | 421 |             close(fenceFd); | 
 | 422 |         } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 423 |         return i; | 
 | 424 |     } | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 425 |     if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) { | 
 | 426 |         if (fenceFd >= 0) { | 
 | 427 |             close(fenceFd); | 
 | 428 |         } | 
 | 429 |         return OK; | 
 | 430 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 431 |     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); | 
 | 432 |     mGraphicBufferProducer->cancelBuffer(i, fence); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 433 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 434 |     if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) { | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 435 |         mSharedBufferHasBeenQueued = true; | 
 | 436 |     } | 
 | 437 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 438 |     return OK; | 
 | 439 | } | 
 | 440 |  | 
 | 441 | int Surface::getSlotFromBufferLocked( | 
 | 442 |         android_native_buffer_t* buffer) const { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 443 |     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { | 
 | 444 |         if (mSlots[i].buffer != NULL && | 
 | 445 |                 mSlots[i].buffer->handle == buffer->handle) { | 
 | 446 |             return i; | 
| Jamie Gennis | aca4e22 | 2010-07-15 17:29:15 -0700 | [diff] [blame] | 447 |         } | 
 | 448 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 449 |     ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle); | 
 | 450 |     return BAD_VALUE; | 
| Mathias Agopian | a0c30e9 | 2010-06-04 18:26:32 -0700 | [diff] [blame] | 451 | } | 
 | 452 |  | 
| Igor Murashkin | 7d2d160 | 2013-11-12 18:02:20 -0800 | [diff] [blame] | 453 | int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 454 |     ALOGV("Surface::lockBuffer"); | 
 | 455 |     Mutex::Autolock lock(mMutex); | 
 | 456 |     return OK; | 
 | 457 | } | 
| Mathias Agopian | 631f358 | 2010-05-25 17:51:34 -0700 | [diff] [blame] | 458 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 459 | int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { | 
 | 460 |     ATRACE_CALL(); | 
 | 461 |     ALOGV("Surface::queueBuffer"); | 
 | 462 |     Mutex::Autolock lock(mMutex); | 
 | 463 |     int64_t timestamp; | 
| Andy McFadden | 3c25621 | 2013-08-16 14:55:39 -0700 | [diff] [blame] | 464 |     bool isAutoTimestamp = false; | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 465 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 466 |     if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) { | 
| Andy McFadden | 4b49e08 | 2013-08-02 15:31:45 -0700 | [diff] [blame] | 467 |         timestamp = systemTime(SYSTEM_TIME_MONOTONIC); | 
| Andy McFadden | 3c25621 | 2013-08-16 14:55:39 -0700 | [diff] [blame] | 468 |         isAutoTimestamp = true; | 
| Andy McFadden | 4b49e08 | 2013-08-02 15:31:45 -0700 | [diff] [blame] | 469 |         ALOGV("Surface::queueBuffer making up timestamp: %.2f ms", | 
| Colin Cross | 9a80d50 | 2016-09-27 14:12:48 -0700 | [diff] [blame] | 470 |             timestamp / 1000000.0); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 471 |     } else { | 
 | 472 |         timestamp = mTimestamp; | 
| Mathias Agopian | 631f358 | 2010-05-25 17:51:34 -0700 | [diff] [blame] | 473 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 474 |     int i = getSlotFromBufferLocked(buffer); | 
 | 475 |     if (i < 0) { | 
| Taiju Tsuiki | 4d0cd3f | 2015-04-30 22:15:33 +0900 | [diff] [blame] | 476 |         if (fenceFd >= 0) { | 
 | 477 |             close(fenceFd); | 
 | 478 |         } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 479 |         return i; | 
 | 480 |     } | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 481 |     if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) { | 
 | 482 |         if (fenceFd >= 0) { | 
 | 483 |             close(fenceFd); | 
 | 484 |         } | 
 | 485 |         return OK; | 
 | 486 |     } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 487 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 488 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 489 |     // Make sure the crop rectangle is entirely inside the buffer. | 
| Pablo Ceballos | 60d6922 | 2015-08-07 14:47:20 -0700 | [diff] [blame] | 490 |     Rect crop(Rect::EMPTY_RECT); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 491 |     mCrop.intersect(Rect(buffer->width, buffer->height), &crop); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 492 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 493 |     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); | 
 | 494 |     IGraphicBufferProducer::QueueBufferOutput output; | 
| Andy McFadden | 3c25621 | 2013-08-16 14:55:39 -0700 | [diff] [blame] | 495 |     IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp, | 
| Eino-Ville Talvala | 82c6bcc | 2015-02-19 16:10:43 -0800 | [diff] [blame] | 496 |             mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform, | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 497 |             fence, mStickyTransform, mEnableFrameTimestamps); | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 498 |  | 
| Dan Stoza | c62acbd | 2015-04-21 16:42:49 -0700 | [diff] [blame] | 499 |     if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) { | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 500 |         input.setSurfaceDamage(Region::INVALID_REGION); | 
 | 501 |     } else { | 
| Dan Stoza | db4850c | 2015-06-25 16:10:18 -0700 | [diff] [blame] | 502 |         // Here we do two things: | 
 | 503 |         // 1) The surface damage was specified using the OpenGL ES convention of | 
 | 504 |         //    the origin being in the bottom-left corner. Here we flip to the | 
 | 505 |         //    convention that the rest of the system uses (top-left corner) by | 
 | 506 |         //    subtracting all top/bottom coordinates from the buffer height. | 
 | 507 |         // 2) If the buffer is coming in rotated (for example, because the EGL | 
 | 508 |         //    implementation is reacting to the transform hint coming back from | 
 | 509 |         //    SurfaceFlinger), the surface damage needs to be rotated the | 
 | 510 |         //    opposite direction, since it was generated assuming an unrotated | 
 | 511 |         //    buffer (the app doesn't know that the EGL implementation is | 
 | 512 |         //    reacting to the transform hint behind its back). The | 
 | 513 |         //    transformations in the switch statement below apply those | 
 | 514 |         //    complementary rotations (e.g., if 90 degrees, rotate 270 degrees). | 
 | 515 |  | 
 | 516 |         int width = buffer->width; | 
| Dan Stoza | 0e65e6c | 2015-05-26 13:22:27 -0700 | [diff] [blame] | 517 |         int height = buffer->height; | 
| Dan Stoza | db4850c | 2015-06-25 16:10:18 -0700 | [diff] [blame] | 518 |         bool rotated90 = (mTransform ^ mStickyTransform) & | 
 | 519 |                 NATIVE_WINDOW_TRANSFORM_ROT_90; | 
 | 520 |         if (rotated90) { | 
 | 521 |             std::swap(width, height); | 
| Dan Stoza | 0e65e6c | 2015-05-26 13:22:27 -0700 | [diff] [blame] | 522 |         } | 
| Dan Stoza | db4850c | 2015-06-25 16:10:18 -0700 | [diff] [blame] | 523 |  | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 524 |         Region flippedRegion; | 
 | 525 |         for (auto rect : mDirtyRegion) { | 
| Dan Stoza | db4850c | 2015-06-25 16:10:18 -0700 | [diff] [blame] | 526 |             int left = rect.left; | 
 | 527 |             int right = rect.right; | 
 | 528 |             int top = height - rect.bottom; // Flip from OpenGL convention | 
 | 529 |             int bottom = height - rect.top; // Flip from OpenGL convention | 
 | 530 |             switch (mTransform ^ mStickyTransform) { | 
 | 531 |                 case NATIVE_WINDOW_TRANSFORM_ROT_90: { | 
 | 532 |                     // Rotate 270 degrees | 
 | 533 |                     Rect flippedRect{top, width - right, bottom, width - left}; | 
 | 534 |                     flippedRegion.orSelf(flippedRect); | 
 | 535 |                     break; | 
 | 536 |                 } | 
 | 537 |                 case NATIVE_WINDOW_TRANSFORM_ROT_180: { | 
 | 538 |                     // Rotate 180 degrees | 
 | 539 |                     Rect flippedRect{width - right, height - bottom, | 
 | 540 |                             width - left, height - top}; | 
 | 541 |                     flippedRegion.orSelf(flippedRect); | 
 | 542 |                     break; | 
 | 543 |                 } | 
 | 544 |                 case NATIVE_WINDOW_TRANSFORM_ROT_270: { | 
 | 545 |                     // Rotate 90 degrees | 
 | 546 |                     Rect flippedRect{height - bottom, left, | 
 | 547 |                             height - top, right}; | 
 | 548 |                     flippedRegion.orSelf(flippedRect); | 
 | 549 |                     break; | 
 | 550 |                 } | 
 | 551 |                 default: { | 
 | 552 |                     Rect flippedRect{left, top, right, bottom}; | 
 | 553 |                     flippedRegion.orSelf(flippedRect); | 
 | 554 |                     break; | 
 | 555 |                 } | 
 | 556 |             } | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 557 |         } | 
 | 558 |  | 
 | 559 |         input.setSurfaceDamage(flippedRegion); | 
 | 560 |     } | 
 | 561 |  | 
| Dan Stoza | 70ccba5 | 2016-07-01 14:00:40 -0700 | [diff] [blame] | 562 |     nsecs_t now = systemTime(); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 563 |     status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output); | 
| Dan Stoza | 70ccba5 | 2016-07-01 14:00:40 -0700 | [diff] [blame] | 564 |     mLastQueueDuration = systemTime() - now; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 565 |     if (err != OK)  { | 
 | 566 |         ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err); | 
 | 567 |     } | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 568 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 569 |     if (mEnableFrameTimestamps) { | 
 | 570 |         mFrameEventHistory.applyDelta(output.frameTimestamps); | 
 | 571 |         // Update timestamps with the local acquire fence. | 
 | 572 |         // The consumer doesn't send it back to prevent us from having two | 
 | 573 |         // file descriptors of the same fence. | 
| Brian Anderson | 3d4039d | 2016-09-23 16:31:30 -0700 | [diff] [blame] | 574 |         mFrameEventHistory.updateAcquireFence(mNextFrameNumber, | 
 | 575 |                 std::make_shared<FenceTime>(std::move(fence))); | 
 | 576 |  | 
 | 577 |         // Cache timestamps of signaled fences so we can close their file | 
 | 578 |         // descriptors. | 
 | 579 |         mFrameEventHistory.updateSignalTimes(); | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 580 |     } | 
 | 581 |  | 
 | 582 |     mDefaultWidth = output.width; | 
 | 583 |     mDefaultHeight = output.height; | 
 | 584 |     mNextFrameNumber = output.nextFrameNumber; | 
| tedbo | 1e7fa9e | 2011-06-22 15:52:53 -0700 | [diff] [blame] | 585 |  | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 586 |     // Disable transform hint if sticky transform is set. | 
 | 587 |     if (mStickyTransform == 0) { | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 588 |         mTransformHint = output.transformHint; | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 589 |     } | 
 | 590 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 591 |     mConsumerRunningBehind = (output.numPendingBuffers >= 2); | 
| Mathias Agopian | 631f358 | 2010-05-25 17:51:34 -0700 | [diff] [blame] | 592 |  | 
| Dan Stoza | c62acbd | 2015-04-21 16:42:49 -0700 | [diff] [blame] | 593 |     if (!mConnectedToCpu) { | 
 | 594 |         // Clear surface damage back to full-buffer | 
 | 595 |         mDirtyRegion = Region::INVALID_REGION; | 
 | 596 |     } | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 597 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 598 |     if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) { | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 599 |         mSharedBufferHasBeenQueued = true; | 
 | 600 |     } | 
 | 601 |  | 
| Robert Carr | 9f31e29 | 2016-04-11 11:15:32 -0700 | [diff] [blame] | 602 |     mQueueBufferCondition.broadcast(); | 
 | 603 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 604 |     return err; | 
 | 605 | } | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 606 |  | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 607 | void Surface::querySupportedTimestampsLocked() const { | 
 | 608 |     // mMutex must be locked when calling this method. | 
 | 609 |  | 
 | 610 |     if (mQueriedSupportedTimestamps) { | 
 | 611 |         return; | 
 | 612 |     } | 
 | 613 |     mQueriedSupportedTimestamps = true; | 
 | 614 |  | 
| Brian Anderson | 3890c39 | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 615 |     std::vector<FrameEvent> supportedFrameTimestamps; | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 616 |     sp<ISurfaceComposer> composer(ComposerService::getComposerService()); | 
 | 617 |     status_t err = composer->getSupportedFrameTimestamps( | 
 | 618 |             &supportedFrameTimestamps); | 
 | 619 |  | 
 | 620 |     if (err != NO_ERROR) { | 
 | 621 |         return; | 
 | 622 |     } | 
 | 623 |  | 
 | 624 |     for (auto sft : supportedFrameTimestamps) { | 
| Brian Anderson | 3890c39 | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 625 |         if (sft == FrameEvent::DISPLAY_PRESENT) { | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 626 |             mFrameTimestampsSupportsPresent = true; | 
| Brian Anderson | 3890c39 | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 627 |         } else if (sft == FrameEvent::DISPLAY_RETIRE) { | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 628 |             mFrameTimestampsSupportsRetire = true; | 
 | 629 |         } | 
 | 630 |     } | 
 | 631 | } | 
 | 632 |  | 
| Mathias Agopian | a67932f | 2011-04-20 14:20:59 -0700 | [diff] [blame] | 633 | int Surface::query(int what, int* value) const { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 634 |     ATRACE_CALL(); | 
 | 635 |     ALOGV("Surface::query"); | 
 | 636 |     { // scope for the lock | 
 | 637 |         Mutex::Autolock lock(mMutex); | 
 | 638 |         switch (what) { | 
 | 639 |             case NATIVE_WINDOW_FORMAT: | 
 | 640 |                 if (mReqFormat) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 641 |                     *value = static_cast<int>(mReqFormat); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 642 |                     return NO_ERROR; | 
 | 643 |                 } | 
 | 644 |                 break; | 
 | 645 |             case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: { | 
 | 646 |                 sp<ISurfaceComposer> composer( | 
 | 647 |                         ComposerService::getComposerService()); | 
 | 648 |                 if (composer->authenticateSurfaceTexture(mGraphicBufferProducer)) { | 
 | 649 |                     *value = 1; | 
 | 650 |                 } else { | 
 | 651 |                     *value = 0; | 
 | 652 |                 } | 
 | 653 |                 return NO_ERROR; | 
 | 654 |             } | 
 | 655 |             case NATIVE_WINDOW_CONCRETE_TYPE: | 
 | 656 |                 *value = NATIVE_WINDOW_SURFACE; | 
 | 657 |                 return NO_ERROR; | 
 | 658 |             case NATIVE_WINDOW_DEFAULT_WIDTH: | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 659 |                 *value = static_cast<int>( | 
 | 660 |                         mUserWidth ? mUserWidth : mDefaultWidth); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 661 |                 return NO_ERROR; | 
 | 662 |             case NATIVE_WINDOW_DEFAULT_HEIGHT: | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 663 |                 *value = static_cast<int>( | 
 | 664 |                         mUserHeight ? mUserHeight : mDefaultHeight); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 665 |                 return NO_ERROR; | 
 | 666 |             case NATIVE_WINDOW_TRANSFORM_HINT: | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 667 |                 *value = static_cast<int>(mTransformHint); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 668 |                 return NO_ERROR; | 
 | 669 |             case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: { | 
 | 670 |                 status_t err = NO_ERROR; | 
 | 671 |                 if (!mConsumerRunningBehind) { | 
 | 672 |                     *value = 0; | 
 | 673 |                 } else { | 
 | 674 |                     err = mGraphicBufferProducer->query(what, value); | 
 | 675 |                     if (err == NO_ERROR) { | 
 | 676 |                         mConsumerRunningBehind = *value; | 
 | 677 |                     } | 
 | 678 |                 } | 
 | 679 |                 return err; | 
 | 680 |             } | 
| Dan Stoza | 70ccba5 | 2016-07-01 14:00:40 -0700 | [diff] [blame] | 681 |             case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: { | 
 | 682 |                 int64_t durationUs = mLastDequeueDuration / 1000; | 
 | 683 |                 *value = durationUs > std::numeric_limits<int>::max() ? | 
 | 684 |                         std::numeric_limits<int>::max() : | 
 | 685 |                         static_cast<int>(durationUs); | 
 | 686 |                 return NO_ERROR; | 
 | 687 |             } | 
 | 688 |             case NATIVE_WINDOW_LAST_QUEUE_DURATION: { | 
 | 689 |                 int64_t durationUs = mLastQueueDuration / 1000; | 
 | 690 |                 *value = durationUs > std::numeric_limits<int>::max() ? | 
 | 691 |                         std::numeric_limits<int>::max() : | 
 | 692 |                         static_cast<int>(durationUs); | 
 | 693 |                 return NO_ERROR; | 
 | 694 |             } | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 695 |             case NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT: { | 
 | 696 |                 querySupportedTimestampsLocked(); | 
 | 697 |                 *value = mFrameTimestampsSupportsPresent ? 1 : 0; | 
 | 698 |                 return NO_ERROR; | 
 | 699 |             } | 
 | 700 |             case NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_RETIRE: { | 
 | 701 |                 querySupportedTimestampsLocked(); | 
 | 702 |                 *value = mFrameTimestampsSupportsRetire ? 1 : 0; | 
 | 703 |                 return NO_ERROR; | 
 | 704 |             } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 705 |         } | 
| Jamie Gennis | 391bbe2 | 2011-03-14 15:00:06 -0700 | [diff] [blame] | 706 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 707 |     return mGraphicBufferProducer->query(what, value); | 
| Eino-Ville Talvala | 1d01a12 | 2011-02-18 11:02:42 -0800 | [diff] [blame] | 708 | } | 
 | 709 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 710 | int Surface::perform(int operation, va_list args) | 
 | 711 | { | 
 | 712 |     int res = NO_ERROR; | 
 | 713 |     switch (operation) { | 
 | 714 |     case NATIVE_WINDOW_CONNECT: | 
 | 715 |         // deprecated. must return NO_ERROR. | 
 | 716 |         break; | 
 | 717 |     case NATIVE_WINDOW_DISCONNECT: | 
 | 718 |         // deprecated. must return NO_ERROR. | 
 | 719 |         break; | 
 | 720 |     case NATIVE_WINDOW_SET_USAGE: | 
 | 721 |         res = dispatchSetUsage(args); | 
 | 722 |         break; | 
 | 723 |     case NATIVE_WINDOW_SET_CROP: | 
 | 724 |         res = dispatchSetCrop(args); | 
 | 725 |         break; | 
 | 726 |     case NATIVE_WINDOW_SET_BUFFER_COUNT: | 
 | 727 |         res = dispatchSetBufferCount(args); | 
 | 728 |         break; | 
 | 729 |     case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: | 
 | 730 |         res = dispatchSetBuffersGeometry(args); | 
 | 731 |         break; | 
 | 732 |     case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: | 
 | 733 |         res = dispatchSetBuffersTransform(args); | 
 | 734 |         break; | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 735 |     case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM: | 
 | 736 |         res = dispatchSetBuffersStickyTransform(args); | 
 | 737 |         break; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 738 |     case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: | 
 | 739 |         res = dispatchSetBuffersTimestamp(args); | 
 | 740 |         break; | 
 | 741 |     case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: | 
 | 742 |         res = dispatchSetBuffersDimensions(args); | 
 | 743 |         break; | 
 | 744 |     case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS: | 
 | 745 |         res = dispatchSetBuffersUserDimensions(args); | 
 | 746 |         break; | 
 | 747 |     case NATIVE_WINDOW_SET_BUFFERS_FORMAT: | 
 | 748 |         res = dispatchSetBuffersFormat(args); | 
 | 749 |         break; | 
 | 750 |     case NATIVE_WINDOW_LOCK: | 
 | 751 |         res = dispatchLock(args); | 
 | 752 |         break; | 
 | 753 |     case NATIVE_WINDOW_UNLOCK_AND_POST: | 
 | 754 |         res = dispatchUnlockAndPost(args); | 
 | 755 |         break; | 
 | 756 |     case NATIVE_WINDOW_SET_SCALING_MODE: | 
 | 757 |         res = dispatchSetScalingMode(args); | 
 | 758 |         break; | 
 | 759 |     case NATIVE_WINDOW_API_CONNECT: | 
 | 760 |         res = dispatchConnect(args); | 
 | 761 |         break; | 
 | 762 |     case NATIVE_WINDOW_API_DISCONNECT: | 
 | 763 |         res = dispatchDisconnect(args); | 
 | 764 |         break; | 
| Rachad | 7cb0d39 | 2014-07-29 17:53:53 -0700 | [diff] [blame] | 765 |     case NATIVE_WINDOW_SET_SIDEBAND_STREAM: | 
 | 766 |         res = dispatchSetSidebandStream(args); | 
 | 767 |         break; | 
| Eino-Ville Talvala | 82c6bcc | 2015-02-19 16:10:43 -0800 | [diff] [blame] | 768 |     case NATIVE_WINDOW_SET_BUFFERS_DATASPACE: | 
 | 769 |         res = dispatchSetBuffersDataSpace(args); | 
 | 770 |         break; | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 771 |     case NATIVE_WINDOW_SET_SURFACE_DAMAGE: | 
 | 772 |         res = dispatchSetSurfaceDamage(args); | 
 | 773 |         break; | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 774 |     case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE: | 
 | 775 |         res = dispatchSetSharedBufferMode(args); | 
| Pablo Ceballos | ccdfd60 | 2015-10-07 15:05:45 -0700 | [diff] [blame] | 776 |         break; | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 777 |     case NATIVE_WINDOW_SET_AUTO_REFRESH: | 
 | 778 |         res = dispatchSetAutoRefresh(args); | 
 | 779 |         break; | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 780 |     case NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS: | 
 | 781 |         res = dispatchEnableFrameTimestamps(args); | 
 | 782 |         break; | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 783 |     case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS: | 
 | 784 |         res = dispatchGetFrameTimestamps(args); | 
 | 785 |         break; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 786 |     default: | 
 | 787 |         res = NAME_NOT_FOUND; | 
 | 788 |         break; | 
 | 789 |     } | 
 | 790 |     return res; | 
 | 791 | } | 
| Mathias Agopian | a138f89 | 2010-05-21 17:24:35 -0700 | [diff] [blame] | 792 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 793 | int Surface::dispatchConnect(va_list args) { | 
 | 794 |     int api = va_arg(args, int); | 
 | 795 |     return connect(api); | 
 | 796 | } | 
| Mathias Agopian | 55fa251 | 2010-03-11 15:06:54 -0800 | [diff] [blame] | 797 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 798 | int Surface::dispatchDisconnect(va_list args) { | 
 | 799 |     int api = va_arg(args, int); | 
 | 800 |     return disconnect(api); | 
 | 801 | } | 
 | 802 |  | 
 | 803 | int Surface::dispatchSetUsage(va_list args) { | 
 | 804 |     int usage = va_arg(args, int); | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 805 |     return setUsage(static_cast<uint32_t>(usage)); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 806 | } | 
 | 807 |  | 
 | 808 | int Surface::dispatchSetCrop(va_list args) { | 
 | 809 |     android_native_rect_t const* rect = va_arg(args, android_native_rect_t*); | 
 | 810 |     return setCrop(reinterpret_cast<Rect const*>(rect)); | 
 | 811 | } | 
 | 812 |  | 
 | 813 | int Surface::dispatchSetBufferCount(va_list args) { | 
 | 814 |     size_t bufferCount = va_arg(args, size_t); | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 815 |     return setBufferCount(static_cast<int32_t>(bufferCount)); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 816 | } | 
 | 817 |  | 
 | 818 | int Surface::dispatchSetBuffersGeometry(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 819 |     uint32_t width = va_arg(args, uint32_t); | 
 | 820 |     uint32_t height = va_arg(args, uint32_t); | 
 | 821 |     PixelFormat format = va_arg(args, PixelFormat); | 
 | 822 |     int err = setBuffersDimensions(width, height); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 823 |     if (err != 0) { | 
 | 824 |         return err; | 
 | 825 |     } | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 826 |     return setBuffersFormat(format); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 827 | } | 
 | 828 |  | 
 | 829 | int Surface::dispatchSetBuffersDimensions(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 830 |     uint32_t width = va_arg(args, uint32_t); | 
 | 831 |     uint32_t height = va_arg(args, uint32_t); | 
 | 832 |     return setBuffersDimensions(width, height); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 833 | } | 
 | 834 |  | 
 | 835 | int Surface::dispatchSetBuffersUserDimensions(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 836 |     uint32_t width = va_arg(args, uint32_t); | 
 | 837 |     uint32_t height = va_arg(args, uint32_t); | 
 | 838 |     return setBuffersUserDimensions(width, height); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 839 | } | 
 | 840 |  | 
 | 841 | int Surface::dispatchSetBuffersFormat(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 842 |     PixelFormat format = va_arg(args, PixelFormat); | 
 | 843 |     return setBuffersFormat(format); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 844 | } | 
 | 845 |  | 
 | 846 | int Surface::dispatchSetScalingMode(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 847 |     int mode = va_arg(args, int); | 
 | 848 |     return setScalingMode(mode); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 849 | } | 
 | 850 |  | 
 | 851 | int Surface::dispatchSetBuffersTransform(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 852 |     uint32_t transform = va_arg(args, uint32_t); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 853 |     return setBuffersTransform(transform); | 
 | 854 | } | 
 | 855 |  | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 856 | int Surface::dispatchSetBuffersStickyTransform(va_list args) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 857 |     uint32_t transform = va_arg(args, uint32_t); | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 858 |     return setBuffersStickyTransform(transform); | 
 | 859 | } | 
 | 860 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 861 | int Surface::dispatchSetBuffersTimestamp(va_list args) { | 
 | 862 |     int64_t timestamp = va_arg(args, int64_t); | 
 | 863 |     return setBuffersTimestamp(timestamp); | 
 | 864 | } | 
 | 865 |  | 
 | 866 | int Surface::dispatchLock(va_list args) { | 
 | 867 |     ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*); | 
 | 868 |     ARect* inOutDirtyBounds = va_arg(args, ARect*); | 
 | 869 |     return lock(outBuffer, inOutDirtyBounds); | 
 | 870 | } | 
 | 871 |  | 
| Igor Murashkin | 7d2d160 | 2013-11-12 18:02:20 -0800 | [diff] [blame] | 872 | int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 873 |     return unlockAndPost(); | 
 | 874 | } | 
 | 875 |  | 
| Rachad | 7cb0d39 | 2014-07-29 17:53:53 -0700 | [diff] [blame] | 876 | int Surface::dispatchSetSidebandStream(va_list args) { | 
 | 877 |     native_handle_t* sH = va_arg(args, native_handle_t*); | 
 | 878 |     sp<NativeHandle> sidebandHandle = NativeHandle::create(sH, false); | 
 | 879 |     setSidebandStream(sidebandHandle); | 
 | 880 |     return OK; | 
 | 881 | } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 882 |  | 
| Eino-Ville Talvala | 82c6bcc | 2015-02-19 16:10:43 -0800 | [diff] [blame] | 883 | int Surface::dispatchSetBuffersDataSpace(va_list args) { | 
 | 884 |     android_dataspace dataspace = | 
 | 885 |             static_cast<android_dataspace>(va_arg(args, int)); | 
 | 886 |     return setBuffersDataSpace(dataspace); | 
 | 887 | } | 
 | 888 |  | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 889 | int Surface::dispatchSetSurfaceDamage(va_list args) { | 
 | 890 |     android_native_rect_t* rects = va_arg(args, android_native_rect_t*); | 
 | 891 |     size_t numRects = va_arg(args, size_t); | 
 | 892 |     setSurfaceDamage(rects, numRects); | 
 | 893 |     return NO_ERROR; | 
 | 894 | } | 
 | 895 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 896 | int Surface::dispatchSetSharedBufferMode(va_list args) { | 
 | 897 |     bool sharedBufferMode = va_arg(args, int); | 
 | 898 |     return setSharedBufferMode(sharedBufferMode); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 899 | } | 
 | 900 |  | 
 | 901 | int Surface::dispatchSetAutoRefresh(va_list args) { | 
 | 902 |     bool autoRefresh = va_arg(args, int); | 
 | 903 |     return setAutoRefresh(autoRefresh); | 
| Pablo Ceballos | ccdfd60 | 2015-10-07 15:05:45 -0700 | [diff] [blame] | 904 | } | 
 | 905 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 906 | int Surface::dispatchEnableFrameTimestamps(va_list args) { | 
 | 907 |     bool enable = va_arg(args, int); | 
 | 908 |     enableFrameTimestamps(enable); | 
 | 909 |     return NO_ERROR; | 
 | 910 | } | 
 | 911 |  | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 912 | int Surface::dispatchGetFrameTimestamps(va_list args) { | 
 | 913 |     uint32_t framesAgo = va_arg(args, uint32_t); | 
| Brian Anderson | dbd0ea8 | 2016-07-22 09:38:59 -0700 | [diff] [blame] | 914 |     nsecs_t* outRequestedPresentTime = va_arg(args, int64_t*); | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 915 |     nsecs_t* outAcquireTime = va_arg(args, int64_t*); | 
 | 916 |     nsecs_t* outRefreshStartTime = va_arg(args, int64_t*); | 
 | 917 |     nsecs_t* outGlCompositionDoneTime = va_arg(args, int64_t*); | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 918 |     nsecs_t* outDisplayPresentTime = va_arg(args, int64_t*); | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 919 |     nsecs_t* outDisplayRetireTime = va_arg(args, int64_t*); | 
 | 920 |     nsecs_t* outReleaseTime = va_arg(args, int64_t*); | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 921 |     return getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo, | 
| Brian Anderson | dbd0ea8 | 2016-07-22 09:38:59 -0700 | [diff] [blame] | 922 |             outRequestedPresentTime, outAcquireTime, outRefreshStartTime, | 
| Brian Anderson | 069b365 | 2016-07-22 10:32:47 -0700 | [diff] [blame] | 923 |             outGlCompositionDoneTime, outDisplayPresentTime, | 
 | 924 |             outDisplayRetireTime, outReleaseTime); | 
| Pablo Ceballos | ce796e7 | 2016-02-04 19:10:51 -0800 | [diff] [blame] | 925 | } | 
 | 926 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 927 | int Surface::connect(int api) { | 
| Dan Stoza | 966b98b | 2015-03-02 22:12:37 -0800 | [diff] [blame] | 928 |     static sp<IProducerListener> listener = new DummyProducerListener(); | 
 | 929 |     return connect(api, listener); | 
 | 930 | } | 
 | 931 |  | 
 | 932 | int Surface::connect(int api, const sp<IProducerListener>& listener) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 933 |     ATRACE_CALL(); | 
 | 934 |     ALOGV("Surface::connect"); | 
 | 935 |     Mutex::Autolock lock(mMutex); | 
 | 936 |     IGraphicBufferProducer::QueueBufferOutput output; | 
| Dan Stoza | f0eaf25 | 2014-03-21 13:05:51 -0700 | [diff] [blame] | 937 |     int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 938 |     if (err == NO_ERROR) { | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 939 |         mDefaultWidth = output.width; | 
 | 940 |         mDefaultHeight = output.height; | 
 | 941 |         mNextFrameNumber = output.nextFrameNumber; | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 942 |  | 
 | 943 |         // Disable transform hint if sticky transform is set. | 
 | 944 |         if (mStickyTransform == 0) { | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 945 |             mTransformHint = output.transformHint; | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 946 |         } | 
 | 947 |  | 
| Brian Anderson | 7c3ba8a | 2016-07-25 12:48:08 -0700 | [diff] [blame] | 948 |         mConsumerRunningBehind = (output.numPendingBuffers >= 2); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 949 |     } | 
 | 950 |     if (!err && api == NATIVE_WINDOW_API_CPU) { | 
 | 951 |         mConnectedToCpu = true; | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 952 |         // Clear the dirty region in case we're switching from a non-CPU API | 
 | 953 |         mDirtyRegion.clear(); | 
 | 954 |     } else if (!err) { | 
 | 955 |         // Initialize the dirty region for tracking surface damage | 
 | 956 |         mDirtyRegion = Region::INVALID_REGION; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 957 |     } | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 958 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 959 |     return err; | 
 | 960 | } | 
 | 961 |  | 
| Mathias Agopian | 365857d | 2013-09-11 19:35:45 -0700 | [diff] [blame] | 962 |  | 
| Robert Carr | 97b9c86 | 2016-09-08 13:54:35 -0700 | [diff] [blame] | 963 | int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) { | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 964 |     ATRACE_CALL(); | 
 | 965 |     ALOGV("Surface::disconnect"); | 
 | 966 |     Mutex::Autolock lock(mMutex); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 967 |     mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; | 
 | 968 |     mSharedBufferHasBeenQueued = false; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 969 |     freeAllBuffers(); | 
| Robert Carr | 97b9c86 | 2016-09-08 13:54:35 -0700 | [diff] [blame] | 970 |     int err = mGraphicBufferProducer->disconnect(api, mode); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 971 |     if (!err) { | 
 | 972 |         mReqFormat = 0; | 
 | 973 |         mReqWidth = 0; | 
 | 974 |         mReqHeight = 0; | 
 | 975 |         mReqUsage = 0; | 
 | 976 |         mCrop.clear(); | 
 | 977 |         mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; | 
 | 978 |         mTransform = 0; | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 979 |         mStickyTransform = 0; | 
 | 980 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 981 |         if (api == NATIVE_WINDOW_API_CPU) { | 
 | 982 |             mConnectedToCpu = false; | 
 | 983 |         } | 
 | 984 |     } | 
 | 985 |     return err; | 
 | 986 | } | 
 | 987 |  | 
| Dan Stoza | d9c4971 | 2015-04-27 11:06:01 -0700 | [diff] [blame] | 988 | int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer, | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 989 |         sp<Fence>* outFence) { | 
 | 990 |     ATRACE_CALL(); | 
 | 991 |     ALOGV("Surface::detachNextBuffer"); | 
 | 992 |  | 
 | 993 |     if (outBuffer == NULL || outFence == NULL) { | 
 | 994 |         return BAD_VALUE; | 
 | 995 |     } | 
 | 996 |  | 
 | 997 |     Mutex::Autolock lock(mMutex); | 
 | 998 |  | 
 | 999 |     sp<GraphicBuffer> buffer(NULL); | 
 | 1000 |     sp<Fence> fence(NULL); | 
 | 1001 |     status_t result = mGraphicBufferProducer->detachNextBuffer( | 
 | 1002 |             &buffer, &fence); | 
 | 1003 |     if (result != NO_ERROR) { | 
 | 1004 |         return result; | 
 | 1005 |     } | 
 | 1006 |  | 
| Dan Stoza | d9c4971 | 2015-04-27 11:06:01 -0700 | [diff] [blame] | 1007 |     *outBuffer = buffer; | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1008 |     if (fence != NULL && fence->isValid()) { | 
 | 1009 |         *outFence = fence; | 
 | 1010 |     } else { | 
 | 1011 |         *outFence = Fence::NO_FENCE; | 
 | 1012 |     } | 
 | 1013 |  | 
| Pablo Ceballos | 23b4abe | 2016-01-08 12:15:22 -0800 | [diff] [blame] | 1014 |     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { | 
 | 1015 |         if (mSlots[i].buffer != NULL && | 
 | 1016 |                 mSlots[i].buffer->handle == buffer->handle) { | 
 | 1017 |             mSlots[i].buffer = NULL; | 
 | 1018 |         } | 
 | 1019 |     } | 
 | 1020 |  | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1021 |     return NO_ERROR; | 
 | 1022 | } | 
 | 1023 |  | 
 | 1024 | int Surface::attachBuffer(ANativeWindowBuffer* buffer) | 
 | 1025 | { | 
 | 1026 |     ATRACE_CALL(); | 
 | 1027 |     ALOGV("Surface::attachBuffer"); | 
 | 1028 |  | 
 | 1029 |     Mutex::Autolock lock(mMutex); | 
 | 1030 |  | 
 | 1031 |     sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer)); | 
| Dan Stoza | 812ed06 | 2015-06-02 15:45:22 -0700 | [diff] [blame] | 1032 |     uint32_t priorGeneration = graphicBuffer->mGenerationNumber; | 
 | 1033 |     graphicBuffer->mGenerationNumber = mGenerationNumber; | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1034 |     int32_t attachedSlot = -1; | 
 | 1035 |     status_t result = mGraphicBufferProducer->attachBuffer( | 
 | 1036 |             &attachedSlot, graphicBuffer); | 
 | 1037 |     if (result != NO_ERROR) { | 
 | 1038 |         ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result); | 
| Dan Stoza | 812ed06 | 2015-06-02 15:45:22 -0700 | [diff] [blame] | 1039 |         graphicBuffer->mGenerationNumber = priorGeneration; | 
| Dan Stoza | 231832e | 2015-03-11 11:55:01 -0700 | [diff] [blame] | 1040 |         return result; | 
 | 1041 |     } | 
 | 1042 |     mSlots[attachedSlot].buffer = graphicBuffer; | 
 | 1043 |  | 
 | 1044 |     return NO_ERROR; | 
 | 1045 | } | 
 | 1046 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1047 | int Surface::setUsage(uint32_t reqUsage) | 
 | 1048 | { | 
 | 1049 |     ALOGV("Surface::setUsage"); | 
 | 1050 |     Mutex::Autolock lock(mMutex); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1051 |     if (reqUsage != mReqUsage) { | 
 | 1052 |         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; | 
 | 1053 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1054 |     mReqUsage = reqUsage; | 
 | 1055 |     return OK; | 
 | 1056 | } | 
 | 1057 |  | 
 | 1058 | int Surface::setCrop(Rect const* rect) | 
 | 1059 | { | 
 | 1060 |     ATRACE_CALL(); | 
 | 1061 |  | 
| Pablo Ceballos | 60d6922 | 2015-08-07 14:47:20 -0700 | [diff] [blame] | 1062 |     Rect realRect(Rect::EMPTY_RECT); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1063 |     if (rect == NULL || rect->isEmpty()) { | 
 | 1064 |         realRect.clear(); | 
 | 1065 |     } else { | 
 | 1066 |         realRect = *rect; | 
| Mathias Agopian | 55fa251 | 2010-03-11 15:06:54 -0800 | [diff] [blame] | 1067 |     } | 
 | 1068 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1069 |     ALOGV("Surface::setCrop rect=[%d %d %d %d]", | 
 | 1070 |             realRect.left, realRect.top, realRect.right, realRect.bottom); | 
 | 1071 |  | 
 | 1072 |     Mutex::Autolock lock(mMutex); | 
 | 1073 |     mCrop = realRect; | 
 | 1074 |     return NO_ERROR; | 
 | 1075 | } | 
 | 1076 |  | 
 | 1077 | int Surface::setBufferCount(int bufferCount) | 
 | 1078 | { | 
 | 1079 |     ATRACE_CALL(); | 
 | 1080 |     ALOGV("Surface::setBufferCount"); | 
 | 1081 |     Mutex::Autolock lock(mMutex); | 
 | 1082 |  | 
| Pablo Ceballos | e5b755a | 2015-08-13 16:18:19 -0700 | [diff] [blame] | 1083 |     status_t err = NO_ERROR; | 
 | 1084 |     if (bufferCount == 0) { | 
 | 1085 |         err = mGraphicBufferProducer->setMaxDequeuedBufferCount(1); | 
 | 1086 |     } else { | 
 | 1087 |         int minUndequeuedBuffers = 0; | 
 | 1088 |         err = mGraphicBufferProducer->query( | 
 | 1089 |                 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers); | 
 | 1090 |         if (err == NO_ERROR) { | 
 | 1091 |             err = mGraphicBufferProducer->setMaxDequeuedBufferCount( | 
 | 1092 |                     bufferCount - minUndequeuedBuffers); | 
 | 1093 |         } | 
 | 1094 |     } | 
| Mathias Agopian | 9014726 | 2010-01-22 11:47:55 -0800 | [diff] [blame] | 1095 |  | 
| Pablo Ceballos | e5b755a | 2015-08-13 16:18:19 -0700 | [diff] [blame] | 1096 |     ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s", | 
 | 1097 |              bufferCount, strerror(-err)); | 
 | 1098 |  | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 1099 |     return err; | 
 | 1100 | } | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 1101 |  | 
| Pablo Ceballos | fa45535 | 2015-08-12 17:47:47 -0700 | [diff] [blame] | 1102 | int Surface::setMaxDequeuedBufferCount(int maxDequeuedBuffers) { | 
 | 1103 |     ATRACE_CALL(); | 
 | 1104 |     ALOGV("Surface::setMaxDequeuedBufferCount"); | 
 | 1105 |     Mutex::Autolock lock(mMutex); | 
 | 1106 |  | 
 | 1107 |     status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount( | 
 | 1108 |             maxDequeuedBuffers); | 
 | 1109 |     ALOGE_IF(err, "IGraphicBufferProducer::setMaxDequeuedBufferCount(%d) " | 
 | 1110 |             "returned %s", maxDequeuedBuffers, strerror(-err)); | 
 | 1111 |  | 
| Pablo Ceballos | fa45535 | 2015-08-12 17:47:47 -0700 | [diff] [blame] | 1112 |     return err; | 
 | 1113 | } | 
 | 1114 |  | 
 | 1115 | int Surface::setAsyncMode(bool async) { | 
 | 1116 |     ATRACE_CALL(); | 
 | 1117 |     ALOGV("Surface::setAsyncMode"); | 
 | 1118 |     Mutex::Autolock lock(mMutex); | 
 | 1119 |  | 
 | 1120 |     status_t err = mGraphicBufferProducer->setAsyncMode(async); | 
 | 1121 |     ALOGE_IF(err, "IGraphicBufferProducer::setAsyncMode(%d) returned %s", | 
 | 1122 |             async, strerror(-err)); | 
 | 1123 |  | 
| Pablo Ceballos | fa45535 | 2015-08-12 17:47:47 -0700 | [diff] [blame] | 1124 |     return err; | 
 | 1125 | } | 
 | 1126 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 1127 | int Surface::setSharedBufferMode(bool sharedBufferMode) { | 
| Pablo Ceballos | ccdfd60 | 2015-10-07 15:05:45 -0700 | [diff] [blame] | 1128 |     ATRACE_CALL(); | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 1129 |     ALOGV("Surface::setSharedBufferMode (%d)", sharedBufferMode); | 
| Pablo Ceballos | ccdfd60 | 2015-10-07 15:05:45 -0700 | [diff] [blame] | 1130 |     Mutex::Autolock lock(mMutex); | 
 | 1131 |  | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 1132 |     status_t err = mGraphicBufferProducer->setSharedBufferMode( | 
 | 1133 |             sharedBufferMode); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1134 |     if (err == NO_ERROR) { | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 1135 |         mSharedBufferMode = sharedBufferMode; | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1136 |     } | 
| Pablo Ceballos | 3559fbf | 2016-03-17 15:50:23 -0700 | [diff] [blame] | 1137 |     ALOGE_IF(err, "IGraphicBufferProducer::setSharedBufferMode(%d) returned" | 
 | 1138 |             "%s", sharedBufferMode, strerror(-err)); | 
| Pablo Ceballos | ccdfd60 | 2015-10-07 15:05:45 -0700 | [diff] [blame] | 1139 |  | 
 | 1140 |     return err; | 
 | 1141 | } | 
 | 1142 |  | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1143 | int Surface::setAutoRefresh(bool autoRefresh) { | 
 | 1144 |     ATRACE_CALL(); | 
 | 1145 |     ALOGV("Surface::setAutoRefresh (%d)", autoRefresh); | 
 | 1146 |     Mutex::Autolock lock(mMutex); | 
 | 1147 |  | 
 | 1148 |     status_t err = mGraphicBufferProducer->setAutoRefresh(autoRefresh); | 
 | 1149 |     if (err == NO_ERROR) { | 
 | 1150 |         mAutoRefresh = autoRefresh; | 
 | 1151 |     } | 
 | 1152 |     ALOGE_IF(err, "IGraphicBufferProducer::setAutoRefresh(%d) returned %s", | 
 | 1153 |             autoRefresh, strerror(-err)); | 
 | 1154 |     return err; | 
 | 1155 | } | 
 | 1156 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1157 | int Surface::setBuffersDimensions(uint32_t width, uint32_t height) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1158 | { | 
 | 1159 |     ATRACE_CALL(); | 
 | 1160 |     ALOGV("Surface::setBuffersDimensions"); | 
 | 1161 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1162 |     if ((width && !height) || (!width && height)) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1163 |         return BAD_VALUE; | 
 | 1164 |  | 
 | 1165 |     Mutex::Autolock lock(mMutex); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1166 |     if (width != mReqWidth || height != mReqHeight) { | 
 | 1167 |         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; | 
 | 1168 |     } | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1169 |     mReqWidth = width; | 
 | 1170 |     mReqHeight = height; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1171 |     return NO_ERROR; | 
 | 1172 | } | 
 | 1173 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1174 | int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1175 | { | 
 | 1176 |     ATRACE_CALL(); | 
 | 1177 |     ALOGV("Surface::setBuffersUserDimensions"); | 
 | 1178 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1179 |     if ((width && !height) || (!width && height)) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1180 |         return BAD_VALUE; | 
 | 1181 |  | 
 | 1182 |     Mutex::Autolock lock(mMutex); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1183 |     if (width != mUserWidth || height != mUserHeight) { | 
 | 1184 |         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; | 
 | 1185 |     } | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1186 |     mUserWidth = width; | 
 | 1187 |     mUserHeight = height; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1188 |     return NO_ERROR; | 
 | 1189 | } | 
 | 1190 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1191 | int Surface::setBuffersFormat(PixelFormat format) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1192 | { | 
 | 1193 |     ALOGV("Surface::setBuffersFormat"); | 
 | 1194 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1195 |     Mutex::Autolock lock(mMutex); | 
| Pablo Ceballos | ff95aab | 2016-01-13 17:09:58 -0800 | [diff] [blame] | 1196 |     if (format != mReqFormat) { | 
 | 1197 |         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; | 
 | 1198 |     } | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1199 |     mReqFormat = format; | 
 | 1200 |     return NO_ERROR; | 
 | 1201 | } | 
 | 1202 |  | 
 | 1203 | int Surface::setScalingMode(int mode) | 
 | 1204 | { | 
 | 1205 |     ATRACE_CALL(); | 
 | 1206 |     ALOGV("Surface::setScalingMode(%d)", mode); | 
 | 1207 |  | 
 | 1208 |     switch (mode) { | 
 | 1209 |         case NATIVE_WINDOW_SCALING_MODE_FREEZE: | 
 | 1210 |         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: | 
 | 1211 |         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: | 
| Robert Carr | c2e7788 | 2015-12-16 18:14:03 -0800 | [diff] [blame] | 1212 |         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1213 |             break; | 
 | 1214 |         default: | 
 | 1215 |             ALOGE("unknown scaling mode: %d", mode); | 
 | 1216 |             return BAD_VALUE; | 
 | 1217 |     } | 
 | 1218 |  | 
 | 1219 |     Mutex::Autolock lock(mMutex); | 
 | 1220 |     mScalingMode = mode; | 
 | 1221 |     return NO_ERROR; | 
 | 1222 | } | 
 | 1223 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1224 | int Surface::setBuffersTransform(uint32_t transform) | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1225 | { | 
 | 1226 |     ATRACE_CALL(); | 
 | 1227 |     ALOGV("Surface::setBuffersTransform"); | 
 | 1228 |     Mutex::Autolock lock(mMutex); | 
 | 1229 |     mTransform = transform; | 
 | 1230 |     return NO_ERROR; | 
 | 1231 | } | 
 | 1232 |  | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1233 | int Surface::setBuffersStickyTransform(uint32_t transform) | 
| Ruben Brunk | 1681d95 | 2014-06-27 15:51:55 -0700 | [diff] [blame] | 1234 | { | 
 | 1235 |     ATRACE_CALL(); | 
 | 1236 |     ALOGV("Surface::setBuffersStickyTransform"); | 
 | 1237 |     Mutex::Autolock lock(mMutex); | 
 | 1238 |     mStickyTransform = transform; | 
 | 1239 |     return NO_ERROR; | 
 | 1240 | } | 
 | 1241 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1242 | int Surface::setBuffersTimestamp(int64_t timestamp) | 
 | 1243 | { | 
 | 1244 |     ALOGV("Surface::setBuffersTimestamp"); | 
 | 1245 |     Mutex::Autolock lock(mMutex); | 
 | 1246 |     mTimestamp = timestamp; | 
 | 1247 |     return NO_ERROR; | 
 | 1248 | } | 
 | 1249 |  | 
| Eino-Ville Talvala | 82c6bcc | 2015-02-19 16:10:43 -0800 | [diff] [blame] | 1250 | int Surface::setBuffersDataSpace(android_dataspace dataSpace) | 
 | 1251 | { | 
 | 1252 |     ALOGV("Surface::setBuffersDataSpace"); | 
 | 1253 |     Mutex::Autolock lock(mMutex); | 
 | 1254 |     mDataSpace = dataSpace; | 
 | 1255 |     return NO_ERROR; | 
 | 1256 | } | 
 | 1257 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1258 | void Surface::freeAllBuffers() { | 
 | 1259 |     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { | 
 | 1260 |         mSlots[i].buffer = 0; | 
 | 1261 |     } | 
 | 1262 | } | 
 | 1263 |  | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 1264 | void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) { | 
 | 1265 |     ATRACE_CALL(); | 
 | 1266 |     ALOGV("Surface::setSurfaceDamage"); | 
 | 1267 |     Mutex::Autolock lock(mMutex); | 
 | 1268 |  | 
| Dan Stoza | c62acbd | 2015-04-21 16:42:49 -0700 | [diff] [blame] | 1269 |     if (mConnectedToCpu || numRects == 0) { | 
| Dan Stoza | 5065a55 | 2015-03-17 16:23:42 -0700 | [diff] [blame] | 1270 |         mDirtyRegion = Region::INVALID_REGION; | 
 | 1271 |         return; | 
 | 1272 |     } | 
 | 1273 |  | 
 | 1274 |     mDirtyRegion.clear(); | 
 | 1275 |     for (size_t r = 0; r < numRects; ++r) { | 
 | 1276 |         // We intentionally flip top and bottom here, since because they're | 
 | 1277 |         // specified with a bottom-left origin, top > bottom, which fails | 
 | 1278 |         // validation in the Region class. We will fix this up when we flip to a | 
 | 1279 |         // top-left origin in queueBuffer. | 
 | 1280 |         Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top); | 
 | 1281 |         mDirtyRegion.orSelf(rect); | 
 | 1282 |     } | 
 | 1283 | } | 
 | 1284 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1285 | // ---------------------------------------------------------------------- | 
 | 1286 | // the lock/unlock APIs must be used from the same thread | 
 | 1287 |  | 
 | 1288 | static status_t copyBlt( | 
 | 1289 |         const sp<GraphicBuffer>& dst, | 
 | 1290 |         const sp<GraphicBuffer>& src, | 
 | 1291 |         const Region& reg) | 
 | 1292 | { | 
 | 1293 |     // src and dst with, height and format must be identical. no verification | 
 | 1294 |     // is done here. | 
 | 1295 |     status_t err; | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1296 |     uint8_t* src_bits = NULL; | 
 | 1297 |     err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), | 
 | 1298 |             reinterpret_cast<void**>(&src_bits)); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1299 |     ALOGE_IF(err, "error locking src buffer %s", strerror(-err)); | 
 | 1300 |  | 
 | 1301 |     uint8_t* dst_bits = NULL; | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1302 |     err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), | 
 | 1303 |             reinterpret_cast<void**>(&dst_bits)); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1304 |     ALOGE_IF(err, "error locking dst buffer %s", strerror(-err)); | 
 | 1305 |  | 
 | 1306 |     Region::const_iterator head(reg.begin()); | 
 | 1307 |     Region::const_iterator tail(reg.end()); | 
 | 1308 |     if (head != tail && src_bits && dst_bits) { | 
 | 1309 |         const size_t bpp = bytesPerPixel(src->format); | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1310 |         const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp; | 
 | 1311 |         const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1312 |  | 
 | 1313 |         while (head != tail) { | 
 | 1314 |             const Rect& r(*head++); | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1315 |             int32_t h = r.height(); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1316 |             if (h <= 0) continue; | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1317 |             size_t size = static_cast<uint32_t>(r.width()) * bpp; | 
 | 1318 |             uint8_t const * s = src_bits + | 
 | 1319 |                     static_cast<uint32_t>(r.left + src->stride * r.top) * bpp; | 
 | 1320 |             uint8_t       * d = dst_bits + | 
 | 1321 |                     static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp; | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1322 |             if (dbpr==sbpr && size==sbpr) { | 
| Dan Stoza | 3be1c6b | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 1323 |                 size *= static_cast<size_t>(h); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1324 |                 h = 1; | 
 | 1325 |             } | 
 | 1326 |             do { | 
 | 1327 |                 memcpy(d, s, size); | 
 | 1328 |                 d += dbpr; | 
 | 1329 |                 s += sbpr; | 
 | 1330 |             } while (--h > 0); | 
 | 1331 |         } | 
 | 1332 |     } | 
 | 1333 |  | 
 | 1334 |     if (src_bits) | 
 | 1335 |         src->unlock(); | 
 | 1336 |  | 
 | 1337 |     if (dst_bits) | 
 | 1338 |         dst->unlock(); | 
 | 1339 |  | 
 | 1340 |     return err; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1341 | } | 
 | 1342 |  | 
| Mathias Agopian | a138f89 | 2010-05-21 17:24:35 -0700 | [diff] [blame] | 1343 | // ---------------------------------------------------------------------------- | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1344 |  | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1345 | status_t Surface::lock( | 
 | 1346 |         ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds) | 
 | 1347 | { | 
 | 1348 |     if (mLockedBuffer != 0) { | 
 | 1349 |         ALOGE("Surface::lock failed, already locked"); | 
 | 1350 |         return INVALID_OPERATION; | 
 | 1351 |     } | 
 | 1352 |  | 
 | 1353 |     if (!mConnectedToCpu) { | 
 | 1354 |         int err = Surface::connect(NATIVE_WINDOW_API_CPU); | 
 | 1355 |         if (err) { | 
 | 1356 |             return err; | 
 | 1357 |         } | 
 | 1358 |         // we're intending to do software rendering from this point | 
 | 1359 |         setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); | 
 | 1360 |     } | 
 | 1361 |  | 
 | 1362 |     ANativeWindowBuffer* out; | 
 | 1363 |     int fenceFd = -1; | 
 | 1364 |     status_t err = dequeueBuffer(&out, &fenceFd); | 
 | 1365 |     ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err)); | 
 | 1366 |     if (err == NO_ERROR) { | 
 | 1367 |         sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out)); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1368 |         const Rect bounds(backBuffer->width, backBuffer->height); | 
 | 1369 |  | 
 | 1370 |         Region newDirtyRegion; | 
 | 1371 |         if (inOutDirtyBounds) { | 
 | 1372 |             newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds)); | 
 | 1373 |             newDirtyRegion.andSelf(bounds); | 
 | 1374 |         } else { | 
 | 1375 |             newDirtyRegion.set(bounds); | 
 | 1376 |         } | 
 | 1377 |  | 
 | 1378 |         // figure out if we can copy the frontbuffer back | 
 | 1379 |         const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); | 
 | 1380 |         const bool canCopyBack = (frontBuffer != 0 && | 
 | 1381 |                 backBuffer->width  == frontBuffer->width && | 
 | 1382 |                 backBuffer->height == frontBuffer->height && | 
 | 1383 |                 backBuffer->format == frontBuffer->format); | 
 | 1384 |  | 
 | 1385 |         if (canCopyBack) { | 
 | 1386 |             // copy the area that is invalid and not repainted this round | 
 | 1387 |             const Region copyback(mDirtyRegion.subtract(newDirtyRegion)); | 
 | 1388 |             if (!copyback.isEmpty()) | 
 | 1389 |                 copyBlt(backBuffer, frontBuffer, copyback); | 
 | 1390 |         } else { | 
 | 1391 |             // if we can't copy-back anything, modify the user's dirty | 
 | 1392 |             // region to make sure they redraw the whole buffer | 
 | 1393 |             newDirtyRegion.set(bounds); | 
 | 1394 |             mDirtyRegion.clear(); | 
 | 1395 |             Mutex::Autolock lock(mMutex); | 
 | 1396 |             for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) { | 
 | 1397 |                 mSlots[i].dirtyRegion.clear(); | 
 | 1398 |             } | 
 | 1399 |         } | 
 | 1400 |  | 
 | 1401 |  | 
 | 1402 |         { // scope for the lock | 
 | 1403 |             Mutex::Autolock lock(mMutex); | 
 | 1404 |             int backBufferSlot(getSlotFromBufferLocked(backBuffer.get())); | 
 | 1405 |             if (backBufferSlot >= 0) { | 
 | 1406 |                 Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion); | 
 | 1407 |                 mDirtyRegion.subtract(dirtyRegion); | 
 | 1408 |                 dirtyRegion = newDirtyRegion; | 
 | 1409 |             } | 
 | 1410 |         } | 
 | 1411 |  | 
 | 1412 |         mDirtyRegion.orSelf(newDirtyRegion); | 
 | 1413 |         if (inOutDirtyBounds) { | 
 | 1414 |             *inOutDirtyBounds = newDirtyRegion.getBounds(); | 
 | 1415 |         } | 
 | 1416 |  | 
 | 1417 |         void* vaddr; | 
| Francis Hart | 8f39601 | 2014-04-01 15:30:53 +0300 | [diff] [blame] | 1418 |         status_t res = backBuffer->lockAsync( | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1419 |                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, | 
| Francis Hart | 8f39601 | 2014-04-01 15:30:53 +0300 | [diff] [blame] | 1420 |                 newDirtyRegion.bounds(), &vaddr, fenceFd); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1421 |  | 
 | 1422 |         ALOGW_IF(res, "failed locking buffer (handle = %p)", | 
 | 1423 |                 backBuffer->handle); | 
 | 1424 |  | 
 | 1425 |         if (res != 0) { | 
 | 1426 |             err = INVALID_OPERATION; | 
 | 1427 |         } else { | 
 | 1428 |             mLockedBuffer = backBuffer; | 
 | 1429 |             outBuffer->width  = backBuffer->width; | 
 | 1430 |             outBuffer->height = backBuffer->height; | 
 | 1431 |             outBuffer->stride = backBuffer->stride; | 
 | 1432 |             outBuffer->format = backBuffer->format; | 
 | 1433 |             outBuffer->bits   = vaddr; | 
 | 1434 |         } | 
 | 1435 |     } | 
 | 1436 |     return err; | 
 | 1437 | } | 
 | 1438 |  | 
 | 1439 | status_t Surface::unlockAndPost() | 
 | 1440 | { | 
 | 1441 |     if (mLockedBuffer == 0) { | 
 | 1442 |         ALOGE("Surface::unlockAndPost failed, no locked buffer"); | 
 | 1443 |         return INVALID_OPERATION; | 
 | 1444 |     } | 
 | 1445 |  | 
| Francis Hart | 8f39601 | 2014-04-01 15:30:53 +0300 | [diff] [blame] | 1446 |     int fd = -1; | 
 | 1447 |     status_t err = mLockedBuffer->unlockAsync(&fd); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1448 |     ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle); | 
 | 1449 |  | 
| Francis Hart | 8f39601 | 2014-04-01 15:30:53 +0300 | [diff] [blame] | 1450 |     err = queueBuffer(mLockedBuffer.get(), fd); | 
| Mathias Agopian | e3c697f | 2013-02-14 17:11:02 -0800 | [diff] [blame] | 1451 |     ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)", | 
 | 1452 |             mLockedBuffer->handle, strerror(-err)); | 
 | 1453 |  | 
 | 1454 |     mPostedBuffer = mLockedBuffer; | 
 | 1455 |     mLockedBuffer = 0; | 
 | 1456 |     return err; | 
 | 1457 | } | 
 | 1458 |  | 
| Robert Carr | 9f31e29 | 2016-04-11 11:15:32 -0700 | [diff] [blame] | 1459 | bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) { | 
 | 1460 |     Mutex::Autolock lock(mMutex); | 
| Pablo Ceballos | bc8c192 | 2016-07-01 14:15:41 -0700 | [diff] [blame] | 1461 |     if (mNextFrameNumber > lastFrame) { | 
| Robert Carr | 9f31e29 | 2016-04-11 11:15:32 -0700 | [diff] [blame] | 1462 |       return true; | 
 | 1463 |     } | 
 | 1464 |     return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK; | 
 | 1465 | } | 
 | 1466 |  | 
| Pablo Ceballos | 8e3e92b | 2016-06-27 17:56:53 -0700 | [diff] [blame] | 1467 | status_t Surface::getUniqueId(uint64_t* outId) const { | 
 | 1468 |     Mutex::Autolock lock(mMutex); | 
 | 1469 |     return mGraphicBufferProducer->getUniqueId(outId); | 
 | 1470 | } | 
 | 1471 |  | 
| Eino-Ville Talvala | 8861291 | 2016-01-06 12:09:11 -0800 | [diff] [blame] | 1472 | namespace view { | 
 | 1473 |  | 
 | 1474 | status_t Surface::writeToParcel(Parcel* parcel) const { | 
 | 1475 |     return writeToParcel(parcel, false); | 
 | 1476 | } | 
 | 1477 |  | 
 | 1478 | status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const { | 
 | 1479 |     if (parcel == nullptr) return BAD_VALUE; | 
 | 1480 |  | 
 | 1481 |     status_t res = OK; | 
 | 1482 |  | 
| Eino-Ville Talvala | 529a103 | 2016-08-29 17:33:08 -0700 | [diff] [blame] | 1483 |     if (!nameAlreadyWritten) { | 
 | 1484 |         res = parcel->writeString16(name); | 
 | 1485 |         if (res != OK) return res; | 
| Eino-Ville Talvala | 8861291 | 2016-01-06 12:09:11 -0800 | [diff] [blame] | 1486 |  | 
| Eino-Ville Talvala | 529a103 | 2016-08-29 17:33:08 -0700 | [diff] [blame] | 1487 |         /* isSingleBuffered defaults to no */ | 
 | 1488 |         res = parcel->writeInt32(0); | 
 | 1489 |         if (res != OK) return res; | 
| Eino-Ville Talvala | 8861291 | 2016-01-06 12:09:11 -0800 | [diff] [blame] | 1490 |     } | 
| Eino-Ville Talvala | 529a103 | 2016-08-29 17:33:08 -0700 | [diff] [blame] | 1491 |  | 
 | 1492 |     res = parcel->writeStrongBinder( | 
 | 1493 |             IGraphicBufferProducer::asBinder(graphicBufferProducer)); | 
 | 1494 |  | 
| Eino-Ville Talvala | 8861291 | 2016-01-06 12:09:11 -0800 | [diff] [blame] | 1495 |     return res; | 
 | 1496 | } | 
 | 1497 |  | 
 | 1498 | status_t Surface::readFromParcel(const Parcel* parcel) { | 
 | 1499 |     return readFromParcel(parcel, false); | 
 | 1500 | } | 
 | 1501 |  | 
 | 1502 | status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) { | 
 | 1503 |     if (parcel == nullptr) return BAD_VALUE; | 
 | 1504 |  | 
| Eino-Ville Talvala | 529a103 | 2016-08-29 17:33:08 -0700 | [diff] [blame] | 1505 |     status_t res = OK; | 
| Eino-Ville Talvala | 8861291 | 2016-01-06 12:09:11 -0800 | [diff] [blame] | 1506 |     if (!nameAlreadyRead) { | 
 | 1507 |         name = readMaybeEmptyString16(parcel); | 
| Eino-Ville Talvala | 529a103 | 2016-08-29 17:33:08 -0700 | [diff] [blame] | 1508 |         // Discard this for now | 
 | 1509 |         int isSingleBuffered; | 
 | 1510 |         res = parcel->readInt32(&isSingleBuffered); | 
 | 1511 |         if (res != OK) { | 
| Eino-Ville Talvala | 7407963 | 2016-09-22 15:04:04 -0700 | [diff] [blame] | 1512 |             ALOGE("Can't read isSingleBuffered"); | 
| Eino-Ville Talvala | 529a103 | 2016-08-29 17:33:08 -0700 | [diff] [blame] | 1513 |             return res; | 
 | 1514 |         } | 
| Eino-Ville Talvala | 8861291 | 2016-01-06 12:09:11 -0800 | [diff] [blame] | 1515 |     } | 
 | 1516 |  | 
 | 1517 |     sp<IBinder> binder; | 
 | 1518 |  | 
| Eino-Ville Talvala | 7407963 | 2016-09-22 15:04:04 -0700 | [diff] [blame] | 1519 |     res = parcel->readNullableStrongBinder(&binder); | 
 | 1520 |     if (res != OK) { | 
 | 1521 |         ALOGE("%s: Can't read strong binder", __FUNCTION__); | 
 | 1522 |         return res; | 
 | 1523 |     } | 
| Eino-Ville Talvala | 8861291 | 2016-01-06 12:09:11 -0800 | [diff] [blame] | 1524 |  | 
 | 1525 |     graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder); | 
 | 1526 |  | 
 | 1527 |     return OK; | 
 | 1528 | } | 
 | 1529 |  | 
 | 1530 | String16 Surface::readMaybeEmptyString16(const Parcel* parcel) { | 
 | 1531 |     size_t len; | 
 | 1532 |     const char16_t* str = parcel->readString16Inplace(&len); | 
 | 1533 |     if (str != nullptr) { | 
 | 1534 |         return String16(str, len); | 
 | 1535 |     } else { | 
 | 1536 |         return String16(); | 
 | 1537 |     } | 
 | 1538 | } | 
 | 1539 |  | 
 | 1540 | } // namespace view | 
 | 1541 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1542 | }; // namespace android |