| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2017 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | //#define LOG_NDEBUG 0 | 
|  | 18 | #undef LOG_TAG | 
|  | 19 | #define LOG_TAG "BufferStateLayer" | 
|  | 20 | #define ATRACE_TAG ATRACE_TAG_GRAPHICS | 
|  | 21 |  | 
| Lloyd Pique | 37c2c9b | 2018-12-04 17:25:10 -0800 | [diff] [blame] | 22 | #include <limits> | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 23 |  | 
| Lloyd Pique | 37c2c9b | 2018-12-04 17:25:10 -0800 | [diff] [blame] | 24 | #include <compositionengine/Display.h> | 
| Lloyd Pique | 0b785d8 | 2018-12-04 17:25:27 -0800 | [diff] [blame] | 25 | #include <compositionengine/Layer.h> | 
| Lloyd Pique | 37c2c9b | 2018-12-04 17:25:10 -0800 | [diff] [blame] | 26 | #include <compositionengine/OutputLayer.h> | 
| Lloyd Pique | 0b785d8 | 2018-12-04 17:25:27 -0800 | [diff] [blame] | 27 | #include <compositionengine/impl/LayerCompositionState.h> | 
| Lloyd Pique | 37c2c9b | 2018-12-04 17:25:10 -0800 | [diff] [blame] | 28 | #include <compositionengine/impl/OutputLayerCompositionState.h> | 
| Marissa Wall | 947d34e | 2019-03-29 14:03:53 -0700 | [diff] [blame] | 29 | #include <gui/BufferQueue.h> | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 30 | #include <private/gui/SyncFeatures.h> | 
| Peiyong Lin | cbc184f | 2018-08-22 13:24:10 -0700 | [diff] [blame] | 31 | #include <renderengine/Image.h> | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 32 |  | 
| Lloyd Pique | 37c2c9b | 2018-12-04 17:25:10 -0800 | [diff] [blame] | 33 | #include "BufferStateLayer.h" | 
|  | 34 | #include "ColorLayer.h" | 
| Mikael Pessa | 90092f4 | 2019-08-26 17:22:04 -0700 | [diff] [blame] | 35 | #include "FrameTracer/FrameTracer.h" | 
| Lloyd Pique | 37c2c9b | 2018-12-04 17:25:10 -0800 | [diff] [blame] | 36 | #include "TimeStats/TimeStats.h" | 
| Valerie Hau | 0bc0915 | 2018-12-20 07:42:47 -0800 | [diff] [blame] | 37 |  | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 38 | namespace android { | 
|  | 39 |  | 
| Lloyd Pique | 42ab75e | 2018-09-12 20:46:03 -0700 | [diff] [blame] | 40 | // clang-format off | 
|  | 41 | const std::array<float, 16> BufferStateLayer::IDENTITY_MATRIX{ | 
|  | 42 | 1, 0, 0, 0, | 
|  | 43 | 0, 1, 0, 0, | 
|  | 44 | 0, 0, 1, 0, | 
|  | 45 | 0, 0, 0, 1 | 
|  | 46 | }; | 
|  | 47 | // clang-format on | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 48 |  | 
| Marissa Wall | 947d34e | 2019-03-29 14:03:53 -0700 | [diff] [blame] | 49 | BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args) | 
|  | 50 | : BufferLayer(args), mHwcSlotGenerator(new HwcSlotGenerator()) { | 
| Vishnu Nair | 6035634 | 2018-11-13 13:00:45 -0800 | [diff] [blame] | 51 | mOverrideScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; | 
| Marissa Wall | 3ff826c | 2019-02-07 11:58:25 -0800 | [diff] [blame] | 52 | mCurrentState.dataspace = ui::Dataspace::V0_SRGB; | 
| Vishnu Nair | 6035634 | 2018-11-13 13:00:45 -0800 | [diff] [blame] | 53 | } | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 54 |  | 
| Alec Mouri | 4545a8a | 2019-08-08 20:05:32 -0700 | [diff] [blame] | 55 | BufferStateLayer::~BufferStateLayer() { | 
|  | 56 | if (mActiveBuffer != nullptr) { | 
|  | 57 | // Ensure that mActiveBuffer is uncached from RenderEngine here, as | 
|  | 58 | // RenderEngine may have been using the buffer as an external texture | 
|  | 59 | // after the client uncached the buffer. | 
|  | 60 | auto& engine(mFlinger->getRenderEngine()); | 
|  | 61 | engine.unbindExternalTextureBuffer(mActiveBuffer->getId()); | 
|  | 62 | } | 
|  | 63 | } | 
|  | 64 |  | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 65 | // ----------------------------------------------------------------------- | 
|  | 66 | // Interface implementation for Layer | 
|  | 67 | // ----------------------------------------------------------------------- | 
| Marissa Wall | fda30bb | 2018-10-12 11:34:28 -0700 | [diff] [blame] | 68 | void BufferStateLayer::onLayerDisplayed(const sp<Fence>& releaseFence) { | 
| Marissa Wall | 5a68a77 | 2018-12-22 17:43:42 -0800 | [diff] [blame] | 69 | // The previous release fence notifies the client that SurfaceFlinger is done with the previous | 
|  | 70 | // buffer that was presented on this layer. The first transaction that came in this frame that | 
|  | 71 | // replaced the previous buffer on this layer needs this release fence, because the fence will | 
|  | 72 | // let the client know when that previous buffer is removed from the screen. | 
|  | 73 | // | 
|  | 74 | // Every other transaction on this layer does not need a release fence because no other | 
|  | 75 | // Transactions that were set on this layer this frame are going to have their preceeding buffer | 
|  | 76 | // removed from the display this frame. | 
|  | 77 | // | 
|  | 78 | // For example, if we have 3 transactions this frame. The first transaction doesn't contain a | 
|  | 79 | // buffer so it doesn't need a previous release fence because the layer still needs the previous | 
|  | 80 | // buffer. The second transaction contains a buffer so it needs a previous release fence because | 
|  | 81 | // the previous buffer will be released this frame. The third transaction also contains a | 
|  | 82 | // buffer. It replaces the buffer in the second transaction. The buffer in the second | 
|  | 83 | // transaction will now no longer be presented so it is released immediately and the third | 
|  | 84 | // transaction doesn't need a previous release fence. | 
|  | 85 | for (auto& handle : mDrawingState.callbackHandles) { | 
|  | 86 | if (handle->releasePreviousBuffer) { | 
|  | 87 | handle->previousReleaseFence = releaseFence; | 
|  | 88 | break; | 
|  | 89 | } | 
|  | 90 | } | 
| Mikael Pessa | 2e1608f | 2019-07-19 11:25:35 -0700 | [diff] [blame] | 91 |  | 
|  | 92 | // Prevent tracing the same release multiple times. | 
|  | 93 | if (mPreviousFrameNumber != mPreviousReleasedFrameNumber) { | 
| Mikael Pessa | 90092f4 | 2019-08-26 17:22:04 -0700 | [diff] [blame] | 94 | mFlinger->mFrameTracer->traceFence(getSequence(), mPreviousBufferId, mPreviousFrameNumber, | 
|  | 95 | std::make_shared<FenceTime>(releaseFence), | 
|  | 96 | FrameTracer::FrameEvent::RELEASE_FENCE); | 
| Mikael Pessa | 2e1608f | 2019-07-19 11:25:35 -0700 | [diff] [blame] | 97 | mPreviousReleasedFrameNumber = mPreviousFrameNumber; | 
|  | 98 | } | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 99 | } | 
|  | 100 |  | 
|  | 101 | void BufferStateLayer::setTransformHint(uint32_t /*orientation*/) const { | 
|  | 102 | // TODO(marissaw): send the transform hint to buffer owner | 
|  | 103 | return; | 
|  | 104 | } | 
|  | 105 |  | 
|  | 106 | void BufferStateLayer::releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) { | 
| Marissa Wall | efb71af | 2019-06-27 14:45:53 -0700 | [diff] [blame] | 107 | mFlinger->getTransactionCompletedThread().finalizePendingCallbackHandles( | 
| Marissa Wall | 5a68a77 | 2018-12-22 17:43:42 -0800 | [diff] [blame] | 108 | mDrawingState.callbackHandles); | 
|  | 109 |  | 
|  | 110 | mDrawingState.callbackHandles = {}; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 111 | } | 
|  | 112 |  | 
| Ana Krulec | 010d219 | 2018-10-08 06:29:54 -0700 | [diff] [blame] | 113 | bool BufferStateLayer::shouldPresentNow(nsecs_t /*expectedPresentTime*/) const { | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 114 | if (getSidebandStreamChanged() || getAutoRefresh()) { | 
|  | 115 | return true; | 
|  | 116 | } | 
|  | 117 |  | 
| Marissa Wall | 024a191 | 2018-08-13 13:55:35 -0700 | [diff] [blame] | 118 | return hasFrameUpdate(); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 119 | } | 
|  | 120 |  | 
| Marissa Wall | e2ffb42 | 2018-10-12 11:33:52 -0700 | [diff] [blame] | 121 | bool BufferStateLayer::willPresentCurrentTransaction() const { | 
|  | 122 | // Returns true if the most recent Transaction applied to CurrentState will be presented. | 
|  | 123 | return getSidebandStreamChanged() || getAutoRefresh() || | 
| Valerie Hau | aa19456 | 2019-02-05 16:21:38 -0800 | [diff] [blame] | 124 | (mCurrentState.modified && | 
|  | 125 | (mCurrentState.buffer != nullptr || mCurrentState.bgColorLayer != nullptr)); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 126 | } | 
|  | 127 |  | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 128 | bool BufferStateLayer::getTransformToDisplayInverse() const { | 
|  | 129 | return mCurrentState.transformToDisplayInverse; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 130 | } | 
|  | 131 |  | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 132 | void BufferStateLayer::pushPendingState() { | 
|  | 133 | if (!mCurrentState.modified) { | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 134 | return; | 
|  | 135 | } | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 136 | mPendingStates.push_back(mCurrentState); | 
|  | 137 | ATRACE_INT(mTransactionName.string(), mPendingStates.size()); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 138 | } | 
|  | 139 |  | 
|  | 140 | bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) { | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 141 | const bool stateUpdateAvailable = !mPendingStates.empty(); | 
|  | 142 | while (!mPendingStates.empty()) { | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 143 | popPendingState(stateToCommit); | 
|  | 144 | } | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 145 | mCurrentStateModified = stateUpdateAvailable && mCurrentState.modified; | 
|  | 146 | mCurrentState.modified = false; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 147 | return stateUpdateAvailable; | 
|  | 148 | } | 
|  | 149 |  | 
| Marissa Wall | 861616d | 2018-10-22 12:52:23 -0700 | [diff] [blame] | 150 | // Crop that applies to the window | 
|  | 151 | Rect BufferStateLayer::getCrop(const Layer::State& /*s*/) const { | 
|  | 152 | return Rect::INVALID_RECT; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 153 | } | 
|  | 154 |  | 
|  | 155 | bool BufferStateLayer::setTransform(uint32_t transform) { | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 156 | if (mCurrentState.transform == transform) return false; | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 157 | mCurrentState.transform = transform; | 
|  | 158 | mCurrentState.modified = true; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 159 | setTransactionFlags(eTransactionNeeded); | 
|  | 160 | return true; | 
|  | 161 | } | 
|  | 162 |  | 
|  | 163 | bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) { | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 164 | if (mCurrentState.transformToDisplayInverse == transformToDisplayInverse) return false; | 
|  | 165 | mCurrentState.sequence++; | 
|  | 166 | mCurrentState.transformToDisplayInverse = transformToDisplayInverse; | 
|  | 167 | mCurrentState.modified = true; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 168 | setTransactionFlags(eTransactionNeeded); | 
|  | 169 | return true; | 
|  | 170 | } | 
|  | 171 |  | 
|  | 172 | bool BufferStateLayer::setCrop(const Rect& crop) { | 
| Marissa Wall | 290ad08 | 2019-03-06 13:23:47 -0800 | [diff] [blame] | 173 | Rect c = crop; | 
|  | 174 | if (c.left < 0) { | 
|  | 175 | c.left = 0; | 
|  | 176 | } | 
|  | 177 | if (c.top < 0) { | 
|  | 178 | c.top = 0; | 
|  | 179 | } | 
|  | 180 | // If the width and/or height are < 0, make it [0, 0, -1, -1] so the equality comparision below | 
|  | 181 | // treats all invalid rectangles the same. | 
|  | 182 | if (!c.isValid()) { | 
|  | 183 | c.makeInvalid(); | 
|  | 184 | } | 
|  | 185 |  | 
|  | 186 | if (mCurrentState.crop == c) return false; | 
| Marissa Wall | 290ad08 | 2019-03-06 13:23:47 -0800 | [diff] [blame] | 187 | mCurrentState.crop = c; | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 188 | mCurrentState.modified = true; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 189 | setTransactionFlags(eTransactionNeeded); | 
|  | 190 | return true; | 
|  | 191 | } | 
|  | 192 |  | 
| Marissa Wall | 861616d | 2018-10-22 12:52:23 -0700 | [diff] [blame] | 193 | bool BufferStateLayer::setFrame(const Rect& frame) { | 
|  | 194 | int x = frame.left; | 
|  | 195 | int y = frame.top; | 
|  | 196 | int w = frame.getWidth(); | 
|  | 197 | int h = frame.getHeight(); | 
|  | 198 |  | 
| Marissa Wall | 0f3242d | 2018-12-20 15:10:22 -0800 | [diff] [blame] | 199 | if (x < 0) { | 
|  | 200 | x = 0; | 
|  | 201 | w = frame.right; | 
|  | 202 | } | 
|  | 203 |  | 
|  | 204 | if (y < 0) { | 
|  | 205 | y = 0; | 
|  | 206 | h = frame.bottom; | 
|  | 207 | } | 
|  | 208 |  | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 209 | if (mCurrentState.active.transform.tx() == x && mCurrentState.active.transform.ty() == y && | 
|  | 210 | mCurrentState.active.w == w && mCurrentState.active.h == h) { | 
| Marissa Wall | 861616d | 2018-10-22 12:52:23 -0700 | [diff] [blame] | 211 | return false; | 
|  | 212 | } | 
|  | 213 |  | 
|  | 214 | if (!frame.isValid()) { | 
|  | 215 | x = y = w = h = 0; | 
|  | 216 | } | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 217 | mCurrentState.active.transform.set(x, y); | 
|  | 218 | mCurrentState.active.w = w; | 
|  | 219 | mCurrentState.active.h = h; | 
| Marissa Wall | 861616d | 2018-10-22 12:52:23 -0700 | [diff] [blame] | 220 |  | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 221 | mCurrentState.sequence++; | 
|  | 222 | mCurrentState.modified = true; | 
| Marissa Wall | 861616d | 2018-10-22 12:52:23 -0700 | [diff] [blame] | 223 | setTransactionFlags(eTransactionNeeded); | 
|  | 224 | return true; | 
|  | 225 | } | 
|  | 226 |  | 
| Ady Abraham | 09bd392 | 2019-04-08 10:44:56 -0700 | [diff] [blame] | 227 | bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, nsecs_t postTime, | 
| Marissa Wall | 947d34e | 2019-03-29 14:03:53 -0700 | [diff] [blame] | 228 | nsecs_t desiredPresentTime, const client_cache_t& clientCacheId) { | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 229 | if (mCurrentState.buffer) { | 
| Marissa Wall | fda30bb | 2018-10-12 11:34:28 -0700 | [diff] [blame] | 230 | mReleasePreviousBuffer = true; | 
|  | 231 | } | 
|  | 232 |  | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 233 | mCurrentState.buffer = buffer; | 
| Marissa Wall | 947d34e | 2019-03-29 14:03:53 -0700 | [diff] [blame] | 234 | mCurrentState.clientCacheId = clientCacheId; | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 235 | mCurrentState.modified = true; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 236 | setTransactionFlags(eTransactionNeeded); | 
| Ady Abraham | 09bd392 | 2019-04-08 10:44:56 -0700 | [diff] [blame] | 237 |  | 
| Mikael Pessa | 2e1608f | 2019-07-19 11:25:35 -0700 | [diff] [blame] | 238 | const int32_t layerID = getSequence(); | 
|  | 239 | mFlinger->mTimeStats->setPostTime(layerID, mFrameNumber, getName().c_str(), postTime); | 
| Mikael Pessa | 90092f4 | 2019-08-26 17:22:04 -0700 | [diff] [blame] | 240 | mFlinger->mFrameTracer->traceNewLayer(layerID, getName().c_str()); | 
|  | 241 | mFlinger->mFrameTracer->traceTimestamp(layerID, buffer->getId(), mFrameNumber, postTime, | 
|  | 242 | FrameTracer::FrameEvent::POST); | 
| chaviw | fa67b55 | 2019-08-12 16:51:55 -0700 | [diff] [blame] | 243 | mCurrentState.desiredPresentTime = desiredPresentTime; | 
| Ady Abraham | 09bd392 | 2019-04-08 10:44:56 -0700 | [diff] [blame] | 244 |  | 
|  | 245 | if (mFlinger->mUseSmart90ForVideo) { | 
| chaviw | fa67b55 | 2019-08-12 16:51:55 -0700 | [diff] [blame] | 246 | const nsecs_t presentTime = (desiredPresentTime == -1) ? 0 : desiredPresentTime; | 
| Ady Abraham | a315ce7 | 2019-04-24 14:35:20 -0700 | [diff] [blame] | 247 | mFlinger->mScheduler->addLayerPresentTimeAndHDR(mSchedulerLayerHandle, presentTime, | 
|  | 248 | mCurrentState.hdrMetadata.validTypes != 0); | 
| Ady Abraham | 09bd392 | 2019-04-08 10:44:56 -0700 | [diff] [blame] | 249 | } | 
|  | 250 |  | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 251 | return true; | 
|  | 252 | } | 
|  | 253 |  | 
|  | 254 | bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) { | 
| Marissa Wall | fda30bb | 2018-10-12 11:34:28 -0700 | [diff] [blame] | 255 | // The acquire fences of BufferStateLayers have already signaled before they are set | 
|  | 256 | mCallbackHandleAcquireTime = fence->getSignalTime(); | 
|  | 257 |  | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 258 | mCurrentState.acquireFence = fence; | 
|  | 259 | mCurrentState.modified = true; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 260 | setTransactionFlags(eTransactionNeeded); | 
|  | 261 | return true; | 
|  | 262 | } | 
|  | 263 |  | 
|  | 264 | bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) { | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 265 | if (mCurrentState.dataspace == dataspace) return false; | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 266 | mCurrentState.dataspace = dataspace; | 
|  | 267 | mCurrentState.modified = true; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 268 | setTransactionFlags(eTransactionNeeded); | 
|  | 269 | return true; | 
|  | 270 | } | 
|  | 271 |  | 
|  | 272 | bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) { | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 273 | if (mCurrentState.hdrMetadata == hdrMetadata) return false; | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 274 | mCurrentState.hdrMetadata = hdrMetadata; | 
|  | 275 | mCurrentState.modified = true; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 276 | setTransactionFlags(eTransactionNeeded); | 
|  | 277 | return true; | 
|  | 278 | } | 
|  | 279 |  | 
|  | 280 | bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) { | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 281 | mCurrentState.surfaceDamageRegion = surfaceDamage; | 
|  | 282 | mCurrentState.modified = true; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 283 | setTransactionFlags(eTransactionNeeded); | 
|  | 284 | return true; | 
|  | 285 | } | 
|  | 286 |  | 
|  | 287 | bool BufferStateLayer::setApi(int32_t api) { | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 288 | if (mCurrentState.api == api) return false; | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 289 | mCurrentState.api = api; | 
|  | 290 | mCurrentState.modified = true; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 291 | setTransactionFlags(eTransactionNeeded); | 
|  | 292 | return true; | 
|  | 293 | } | 
|  | 294 |  | 
|  | 295 | bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) { | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 296 | if (mCurrentState.sidebandStream == sidebandStream) return false; | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 297 | mCurrentState.sidebandStream = sidebandStream; | 
|  | 298 | mCurrentState.modified = true; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 299 | setTransactionFlags(eTransactionNeeded); | 
|  | 300 |  | 
|  | 301 | if (!mSidebandStreamChanged.exchange(true)) { | 
|  | 302 | // mSidebandStreamChanged was false | 
|  | 303 | mFlinger->signalLayerUpdate(); | 
|  | 304 | } | 
|  | 305 | return true; | 
|  | 306 | } | 
|  | 307 |  | 
| Marissa Wall | e2ffb42 | 2018-10-12 11:33:52 -0700 | [diff] [blame] | 308 | bool BufferStateLayer::setTransactionCompletedListeners( | 
|  | 309 | const std::vector<sp<CallbackHandle>>& handles) { | 
| Marissa Wall | fda30bb | 2018-10-12 11:34:28 -0700 | [diff] [blame] | 310 | // If there is no handle, we will not send a callback so reset mReleasePreviousBuffer and return | 
| Marissa Wall | e2ffb42 | 2018-10-12 11:33:52 -0700 | [diff] [blame] | 311 | if (handles.empty()) { | 
| Marissa Wall | fda30bb | 2018-10-12 11:34:28 -0700 | [diff] [blame] | 312 | mReleasePreviousBuffer = false; | 
| Marissa Wall | e2ffb42 | 2018-10-12 11:33:52 -0700 | [diff] [blame] | 313 | return false; | 
|  | 314 | } | 
|  | 315 |  | 
|  | 316 | const bool willPresent = willPresentCurrentTransaction(); | 
|  | 317 |  | 
|  | 318 | for (const auto& handle : handles) { | 
| Marissa Wall | fda30bb | 2018-10-12 11:34:28 -0700 | [diff] [blame] | 319 | // If this transaction set a buffer on this layer, release its previous buffer | 
|  | 320 | handle->releasePreviousBuffer = mReleasePreviousBuffer; | 
|  | 321 |  | 
| Marissa Wall | e2ffb42 | 2018-10-12 11:33:52 -0700 | [diff] [blame] | 322 | // If this layer will be presented in this frame | 
|  | 323 | if (willPresent) { | 
| Marissa Wall | fda30bb | 2018-10-12 11:34:28 -0700 | [diff] [blame] | 324 | // If this transaction set an acquire fence on this layer, set its acquire time | 
|  | 325 | handle->acquireTime = mCallbackHandleAcquireTime; | 
|  | 326 |  | 
| Marissa Wall | e2ffb42 | 2018-10-12 11:33:52 -0700 | [diff] [blame] | 327 | // Notify the transaction completed thread that there is a pending latched callback | 
|  | 328 | // handle | 
| Marissa Wall | 5a68a77 | 2018-12-22 17:43:42 -0800 | [diff] [blame] | 329 | mFlinger->getTransactionCompletedThread().registerPendingCallbackHandle(handle); | 
| Marissa Wall | e2ffb42 | 2018-10-12 11:33:52 -0700 | [diff] [blame] | 330 |  | 
|  | 331 | // Store so latched time and release fence can be set | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 332 | mCurrentState.callbackHandles.push_back(handle); | 
| Marissa Wall | e2ffb42 | 2018-10-12 11:33:52 -0700 | [diff] [blame] | 333 |  | 
|  | 334 | } else { // If this layer will NOT need to be relatched and presented this frame | 
|  | 335 | // Notify the transaction completed thread this handle is done | 
| Marissa Wall | efb71af | 2019-06-27 14:45:53 -0700 | [diff] [blame] | 336 | mFlinger->getTransactionCompletedThread().registerUnpresentedCallbackHandle(handle); | 
| Marissa Wall | e2ffb42 | 2018-10-12 11:33:52 -0700 | [diff] [blame] | 337 | } | 
|  | 338 | } | 
|  | 339 |  | 
| Marissa Wall | fda30bb | 2018-10-12 11:34:28 -0700 | [diff] [blame] | 340 | mReleasePreviousBuffer = false; | 
|  | 341 | mCallbackHandleAcquireTime = -1; | 
|  | 342 |  | 
| Marissa Wall | e2ffb42 | 2018-10-12 11:33:52 -0700 | [diff] [blame] | 343 | return willPresent; | 
|  | 344 | } | 
|  | 345 |  | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 346 | bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) { | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 347 | mCurrentState.transparentRegionHint = transparent; | 
|  | 348 | mCurrentState.modified = true; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 349 | setTransactionFlags(eTransactionNeeded); | 
|  | 350 | return true; | 
|  | 351 | } | 
|  | 352 |  | 
| Marissa Wall | 861616d | 2018-10-22 12:52:23 -0700 | [diff] [blame] | 353 | Rect BufferStateLayer::getBufferSize(const State& s) const { | 
|  | 354 | // for buffer state layers we use the display frame size as the buffer size. | 
|  | 355 | if (getActiveWidth(s) < UINT32_MAX && getActiveHeight(s) < UINT32_MAX) { | 
|  | 356 | return Rect(getActiveWidth(s), getActiveHeight(s)); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 357 | } | 
|  | 358 |  | 
| Marissa Wall | 861616d | 2018-10-22 12:52:23 -0700 | [diff] [blame] | 359 | // if the display frame is not defined, use the parent bounds as the buffer size. | 
|  | 360 | const auto& p = mDrawingParent.promote(); | 
|  | 361 | if (p != nullptr) { | 
| Vishnu Nair | 4351ad5 | 2019-02-11 14:13:02 -0800 | [diff] [blame] | 362 | Rect parentBounds = Rect(p->getBounds(Region())); | 
| Marissa Wall | 861616d | 2018-10-22 12:52:23 -0700 | [diff] [blame] | 363 | if (!parentBounds.isEmpty()) { | 
|  | 364 | return parentBounds; | 
|  | 365 | } | 
|  | 366 | } | 
|  | 367 |  | 
| Marissa Wall | 861616d | 2018-10-22 12:52:23 -0700 | [diff] [blame] | 368 | return Rect::INVALID_RECT; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 369 | } | 
| Vishnu Nair | 4351ad5 | 2019-02-11 14:13:02 -0800 | [diff] [blame] | 370 |  | 
|  | 371 | FloatRect BufferStateLayer::computeSourceBounds(const FloatRect& parentBounds) const { | 
|  | 372 | const State& s(getDrawingState()); | 
|  | 373 | // for buffer state layers we use the display frame size as the buffer size. | 
|  | 374 | if (getActiveWidth(s) < UINT32_MAX && getActiveHeight(s) < UINT32_MAX) { | 
|  | 375 | return FloatRect(0, 0, getActiveWidth(s), getActiveHeight(s)); | 
|  | 376 | } | 
|  | 377 |  | 
|  | 378 | // if the display frame is not defined, use the parent bounds as the buffer size. | 
|  | 379 | return parentBounds; | 
|  | 380 | } | 
|  | 381 |  | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 382 | // ----------------------------------------------------------------------- | 
|  | 383 |  | 
|  | 384 | // ----------------------------------------------------------------------- | 
|  | 385 | // Interface implementation for BufferLayer | 
|  | 386 | // ----------------------------------------------------------------------- | 
|  | 387 | bool BufferStateLayer::fenceHasSignaled() const { | 
|  | 388 | if (latchUnsignaledBuffers()) { | 
|  | 389 | return true; | 
|  | 390 | } | 
|  | 391 |  | 
|  | 392 | return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled; | 
|  | 393 | } | 
|  | 394 |  | 
| Dominik Laskowski | a8955dd | 2019-07-10 10:19:09 -0700 | [diff] [blame] | 395 | bool BufferStateLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const { | 
| Ady Abraham | cd1580c | 2019-04-29 15:40:03 -0700 | [diff] [blame] | 396 | if (!hasFrameUpdate() || isRemovedFromCurrentState()) { | 
|  | 397 | return true; | 
|  | 398 | } | 
|  | 399 |  | 
| chaviw | fa67b55 | 2019-08-12 16:51:55 -0700 | [diff] [blame] | 400 | return mCurrentState.desiredPresentTime <= expectedPresentTime; | 
| Ady Abraham | cd1580c | 2019-04-29 15:40:03 -0700 | [diff] [blame] | 401 | } | 
|  | 402 |  | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 403 | nsecs_t BufferStateLayer::getDesiredPresentTime() { | 
| chaviw | fa67b55 | 2019-08-12 16:51:55 -0700 | [diff] [blame] | 404 | return getDrawingState().desiredPresentTime; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 405 | } | 
|  | 406 |  | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 407 | std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const { | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 408 | return std::make_shared<FenceTime>(getDrawingState().acquireFence); | 
|  | 409 | } | 
|  | 410 |  | 
|  | 411 | void BufferStateLayer::getDrawingTransformMatrix(float *matrix) { | 
|  | 412 | std::copy(std::begin(mTransformMatrix), std::end(mTransformMatrix), matrix); | 
|  | 413 | } | 
|  | 414 |  | 
|  | 415 | uint32_t BufferStateLayer::getDrawingTransform() const { | 
|  | 416 | return getDrawingState().transform; | 
|  | 417 | } | 
|  | 418 |  | 
|  | 419 | ui::Dataspace BufferStateLayer::getDrawingDataSpace() const { | 
|  | 420 | return getDrawingState().dataspace; | 
|  | 421 | } | 
|  | 422 |  | 
| Marissa Wall | 861616d | 2018-10-22 12:52:23 -0700 | [diff] [blame] | 423 | // Crop that applies to the buffer | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 424 | Rect BufferStateLayer::getDrawingCrop() const { | 
| Marissa Wall | 861616d | 2018-10-22 12:52:23 -0700 | [diff] [blame] | 425 | const State& s(getDrawingState()); | 
|  | 426 |  | 
|  | 427 | if (s.crop.isEmpty() && s.buffer) { | 
|  | 428 | return s.buffer->getBounds(); | 
| Valerie Hau | 0bc0915 | 2018-12-20 07:42:47 -0800 | [diff] [blame] | 429 | } else if (s.buffer) { | 
|  | 430 | Rect crop = s.crop; | 
|  | 431 | crop.left = std::max(crop.left, 0); | 
|  | 432 | crop.top = std::max(crop.top, 0); | 
|  | 433 | uint32_t bufferWidth = s.buffer->getWidth(); | 
|  | 434 | uint32_t bufferHeight = s.buffer->getHeight(); | 
|  | 435 | if (bufferHeight <= std::numeric_limits<int32_t>::max() && | 
|  | 436 | bufferWidth <= std::numeric_limits<int32_t>::max()) { | 
|  | 437 | crop.right = std::min(crop.right, static_cast<int32_t>(bufferWidth)); | 
|  | 438 | crop.bottom = std::min(crop.bottom, static_cast<int32_t>(bufferHeight)); | 
|  | 439 | } | 
|  | 440 | if (!crop.isValid()) { | 
|  | 441 | // Crop rect is out of bounds, return whole buffer | 
|  | 442 | return s.buffer->getBounds(); | 
|  | 443 | } | 
|  | 444 | return crop; | 
| Marissa Wall | 861616d | 2018-10-22 12:52:23 -0700 | [diff] [blame] | 445 | } | 
|  | 446 | return s.crop; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 447 | } | 
|  | 448 |  | 
|  | 449 | uint32_t BufferStateLayer::getDrawingScalingMode() const { | 
| Marissa Wall | ec463ac | 2018-10-08 12:35:04 -0700 | [diff] [blame] | 450 | return NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 451 | } | 
|  | 452 |  | 
|  | 453 | Region BufferStateLayer::getDrawingSurfaceDamage() const { | 
| Marissa Wall | 0ef8d60 | 2019-04-23 14:09:28 -0700 | [diff] [blame] | 454 | return getDrawingState().surfaceDamageRegion; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 455 | } | 
|  | 456 |  | 
|  | 457 | const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const { | 
|  | 458 | return getDrawingState().hdrMetadata; | 
|  | 459 | } | 
|  | 460 |  | 
|  | 461 | int BufferStateLayer::getDrawingApi() const { | 
|  | 462 | return getDrawingState().api; | 
|  | 463 | } | 
|  | 464 |  | 
|  | 465 | PixelFormat BufferStateLayer::getPixelFormat() const { | 
| Marissa Wall | 5aec641 | 2018-11-14 11:49:18 -0800 | [diff] [blame] | 466 | if (!mActiveBuffer) { | 
|  | 467 | return PIXEL_FORMAT_NONE; | 
|  | 468 | } | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 469 | return mActiveBuffer->format; | 
|  | 470 | } | 
|  | 471 |  | 
| Dominik Laskowski | a8955dd | 2019-07-10 10:19:09 -0700 | [diff] [blame] | 472 | uint64_t BufferStateLayer::getFrameNumber(nsecs_t /*expectedPresentTime*/) const { | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 473 | return mFrameNumber; | 
|  | 474 | } | 
|  | 475 |  | 
|  | 476 | bool BufferStateLayer::getAutoRefresh() const { | 
|  | 477 | // TODO(marissaw): support shared buffer mode | 
|  | 478 | return false; | 
|  | 479 | } | 
|  | 480 |  | 
|  | 481 | bool BufferStateLayer::getSidebandStreamChanged() const { | 
|  | 482 | return mSidebandStreamChanged.load(); | 
|  | 483 | } | 
|  | 484 |  | 
| Vishnu Nair | 6194e2e | 2019-02-06 12:58:39 -0800 | [diff] [blame] | 485 | bool BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) { | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 486 | if (mSidebandStreamChanged.exchange(false)) { | 
|  | 487 | const State& s(getDrawingState()); | 
|  | 488 | // mSidebandStreamChanged was true | 
| Lloyd Pique | 0b785d8 | 2018-12-04 17:25:27 -0800 | [diff] [blame] | 489 | LOG_ALWAYS_FATAL_IF(!getCompositionLayer()); | 
|  | 490 | mSidebandStream = s.sidebandStream; | 
|  | 491 | getCompositionLayer()->editState().frontEnd.sidebandStream = mSidebandStream; | 
|  | 492 | if (mSidebandStream != nullptr) { | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 493 | setTransactionFlags(eTransactionNeeded); | 
|  | 494 | mFlinger->setTransactionFlags(eTraversalNeeded); | 
|  | 495 | } | 
|  | 496 | recomputeVisibleRegions = true; | 
|  | 497 |  | 
| Vishnu Nair | 6194e2e | 2019-02-06 12:58:39 -0800 | [diff] [blame] | 498 | return true; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 499 | } | 
| Vishnu Nair | 6194e2e | 2019-02-06 12:58:39 -0800 | [diff] [blame] | 500 | return false; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 501 | } | 
|  | 502 |  | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 503 | bool BufferStateLayer::hasFrameUpdate() const { | 
| Valerie Hau | aa19456 | 2019-02-05 16:21:38 -0800 | [diff] [blame] | 504 | const State& c(getCurrentState()); | 
|  | 505 | return mCurrentStateModified && (c.buffer != nullptr || c.bgColorLayer != nullptr); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 506 | } | 
|  | 507 |  | 
|  | 508 | void BufferStateLayer::setFilteringEnabled(bool enabled) { | 
|  | 509 | GLConsumer::computeTransformMatrix(mTransformMatrix.data(), mActiveBuffer, mCurrentCrop, | 
|  | 510 | mCurrentTransform, enabled); | 
|  | 511 | } | 
|  | 512 |  | 
| Alec Mouri | 39801c0 | 2018-10-10 10:44:47 -0700 | [diff] [blame] | 513 | status_t BufferStateLayer::bindTextureImage() { | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 514 | const State& s(getDrawingState()); | 
|  | 515 | auto& engine(mFlinger->getRenderEngine()); | 
|  | 516 |  | 
| Alec Mouri | b5c4f35 | 2019-02-19 19:46:38 -0800 | [diff] [blame] | 517 | return engine.bindExternalTextureBuffer(mTextureName, s.buffer, s.acquireFence); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 518 | } | 
|  | 519 |  | 
| Dominik Laskowski | a8955dd | 2019-07-10 10:19:09 -0700 | [diff] [blame] | 520 | status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime, | 
|  | 521 | nsecs_t /*expectedPresentTime*/) { | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 522 | const State& s(getDrawingState()); | 
|  | 523 |  | 
|  | 524 | if (!s.buffer) { | 
| Valerie Hau | aa19456 | 2019-02-05 16:21:38 -0800 | [diff] [blame] | 525 | if (s.bgColorLayer) { | 
|  | 526 | for (auto& handle : mDrawingState.callbackHandles) { | 
|  | 527 | handle->latchTime = latchTime; | 
|  | 528 | } | 
|  | 529 | } | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 530 | return NO_ERROR; | 
|  | 531 | } | 
|  | 532 |  | 
| Yiwei Zhang | 9689e2f | 2018-05-11 12:33:23 -0700 | [diff] [blame] | 533 | const int32_t layerID = getSequence(); | 
|  | 534 |  | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 535 | // Reject if the layer is invalid | 
|  | 536 | uint32_t bufferWidth = s.buffer->width; | 
|  | 537 | uint32_t bufferHeight = s.buffer->height; | 
|  | 538 |  | 
| Peiyong Lin | efefaac | 2018-08-17 12:27:51 -0700 | [diff] [blame] | 539 | if (s.transform & ui::Transform::ROT_90) { | 
| Peiyong Lin | 3db4234 | 2018-08-16 09:15:59 -0700 | [diff] [blame] | 540 | std::swap(bufferWidth, bufferHeight); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 541 | } | 
|  | 542 |  | 
|  | 543 | if (s.transformToDisplayInverse) { | 
|  | 544 | uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform(); | 
| Peiyong Lin | efefaac | 2018-08-17 12:27:51 -0700 | [diff] [blame] | 545 | if (invTransform & ui::Transform::ROT_90) { | 
| Peiyong Lin | 3db4234 | 2018-08-16 09:15:59 -0700 | [diff] [blame] | 546 | std::swap(bufferWidth, bufferHeight); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 547 | } | 
|  | 548 | } | 
|  | 549 |  | 
| Vishnu Nair | 6035634 | 2018-11-13 13:00:45 -0800 | [diff] [blame] | 550 | if (getEffectiveScalingMode() == NATIVE_WINDOW_SCALING_MODE_FREEZE && | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 551 | (s.active.w != bufferWidth || s.active.h != bufferHeight)) { | 
|  | 552 | ALOGE("[%s] rejecting buffer: " | 
|  | 553 | "bufferWidth=%d, bufferHeight=%d, front.active.{w=%d, h=%d}", | 
|  | 554 | mName.string(), bufferWidth, bufferHeight, s.active.w, s.active.h); | 
| Dominik Laskowski | a8955dd | 2019-07-10 10:19:09 -0700 | [diff] [blame] | 555 | mFlinger->mTimeStats->removeTimeRecord(layerID, mFrameNumber); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 556 | return BAD_VALUE; | 
|  | 557 | } | 
|  | 558 |  | 
| Marissa Wall | 5a68a77 | 2018-12-22 17:43:42 -0800 | [diff] [blame] | 559 | for (auto& handle : mDrawingState.callbackHandles) { | 
|  | 560 | handle->latchTime = latchTime; | 
|  | 561 | } | 
| Marissa Wall | e2ffb42 | 2018-10-12 11:33:52 -0700 | [diff] [blame] | 562 |  | 
| Alec Mouri | 56e538f | 2019-01-14 15:22:01 -0800 | [diff] [blame] | 563 | if (!SyncFeatures::getInstance().useNativeFenceSync()) { | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 564 | // Bind the new buffer to the GL texture. | 
|  | 565 | // | 
|  | 566 | // Older devices require the "implicit" synchronization provided | 
|  | 567 | // by glEGLImageTargetTexture2DOES, which this method calls.  Newer | 
|  | 568 | // devices will either call this in Layer::onDraw, or (if it's not | 
|  | 569 | // a GL-composited layer) not at all. | 
| Lloyd Pique | 0449b0f | 2018-12-20 16:23:45 -0800 | [diff] [blame] | 570 | status_t err = bindTextureImage(); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 571 | if (err != NO_ERROR) { | 
| Yiwei Zhang | af8ee94 | 2018-11-22 00:15:23 -0800 | [diff] [blame] | 572 | mFlinger->mTimeStats->onDestroy(layerID); | 
| Mikael Pessa | 90092f4 | 2019-08-26 17:22:04 -0700 | [diff] [blame] | 573 | mFlinger->mFrameTracer->onDestroy(layerID); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 574 | return BAD_VALUE; | 
|  | 575 | } | 
|  | 576 | } | 
|  | 577 |  | 
| Mikael Pessa | 2e1608f | 2019-07-19 11:25:35 -0700 | [diff] [blame] | 578 | const uint64_t bufferID = getCurrentBufferId(); | 
| Dominik Laskowski | a8955dd | 2019-07-10 10:19:09 -0700 | [diff] [blame] | 579 | mFlinger->mTimeStats->setAcquireFence(layerID, mFrameNumber, getCurrentFenceTime()); | 
| Mikael Pessa | 90092f4 | 2019-08-26 17:22:04 -0700 | [diff] [blame] | 580 | mFlinger->mFrameTracer->traceFence(layerID, bufferID, mFrameNumber, getCurrentFenceTime(), | 
|  | 581 | FrameTracer::FrameEvent::ACQUIRE_FENCE); | 
| Dominik Laskowski | a8955dd | 2019-07-10 10:19:09 -0700 | [diff] [blame] | 582 | mFlinger->mTimeStats->setLatchTime(layerID, mFrameNumber, latchTime); | 
| Mikael Pessa | 90092f4 | 2019-08-26 17:22:04 -0700 | [diff] [blame] | 583 | mFlinger->mFrameTracer->traceTimestamp(layerID, bufferID, mFrameNumber, latchTime, | 
|  | 584 | FrameTracer::FrameEvent::LATCH); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 585 |  | 
| Marissa Wall | 16c112d | 2019-03-20 13:21:13 -0700 | [diff] [blame] | 586 | mCurrentStateModified = false; | 
|  | 587 |  | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 588 | return NO_ERROR; | 
|  | 589 | } | 
|  | 590 |  | 
|  | 591 | status_t BufferStateLayer::updateActiveBuffer() { | 
|  | 592 | const State& s(getDrawingState()); | 
|  | 593 |  | 
|  | 594 | if (s.buffer == nullptr) { | 
|  | 595 | return BAD_VALUE; | 
|  | 596 | } | 
|  | 597 |  | 
| Mikael Pessa | 2e1608f | 2019-07-19 11:25:35 -0700 | [diff] [blame] | 598 | mPreviousBufferId = getCurrentBufferId(); | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 599 | mActiveBuffer = s.buffer; | 
| Alec Mouri | e7d1d4a | 2019-02-05 01:13:46 +0000 | [diff] [blame] | 600 | mActiveBufferFence = s.acquireFence; | 
| Lloyd Pique | 0b785d8 | 2018-12-04 17:25:27 -0800 | [diff] [blame] | 601 | auto& layerCompositionState = getCompositionLayer()->editState().frontEnd; | 
|  | 602 | layerCompositionState.buffer = mActiveBuffer; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 603 |  | 
|  | 604 | return NO_ERROR; | 
|  | 605 | } | 
|  | 606 |  | 
|  | 607 | status_t BufferStateLayer::updateFrameNumber(nsecs_t /*latchTime*/) { | 
|  | 608 | // TODO(marissaw): support frame history events | 
| Mikael Pessa | 2e1608f | 2019-07-19 11:25:35 -0700 | [diff] [blame] | 609 | mPreviousFrameNumber = mCurrentFrameNumber; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 610 | mCurrentFrameNumber = mFrameNumber; | 
|  | 611 | return NO_ERROR; | 
|  | 612 | } | 
|  | 613 |  | 
| Lloyd Pique | f527548 | 2019-01-29 18:42:42 -0800 | [diff] [blame] | 614 | void BufferStateLayer::latchPerFrameState( | 
|  | 615 | compositionengine::LayerFECompositionState& compositionState) const { | 
|  | 616 | BufferLayer::latchPerFrameState(compositionState); | 
|  | 617 | if (compositionState.compositionType == Hwc2::IComposerClient::Composition::SIDEBAND) { | 
|  | 618 | return; | 
|  | 619 | } | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 620 |  | 
|  | 621 | const State& s(getDrawingState()); | 
|  | 622 |  | 
| Lloyd Pique | f527548 | 2019-01-29 18:42:42 -0800 | [diff] [blame] | 623 | compositionState.buffer = s.buffer; | 
|  | 624 | compositionState.bufferSlot = mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId); | 
|  | 625 | compositionState.acquireFence = s.acquireFence; | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 626 |  | 
|  | 627 | mFrameNumber++; | 
|  | 628 | } | 
|  | 629 |  | 
|  | 630 | void BufferStateLayer::onFirstRef() { | 
| Dan Stoza | 7b1b5a8 | 2018-07-31 16:00:21 -0700 | [diff] [blame] | 631 | BufferLayer::onFirstRef(); | 
|  | 632 |  | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 633 | if (const auto display = mFlinger->getDefaultDisplayDevice()) { | 
|  | 634 | updateTransformHint(display); | 
|  | 635 | } | 
|  | 636 | } | 
|  | 637 |  | 
| Marissa Wall | 947d34e | 2019-03-29 14:03:53 -0700 | [diff] [blame] | 638 | void BufferStateLayer::HwcSlotGenerator::bufferErased(const client_cache_t& clientCacheId) { | 
|  | 639 | std::lock_guard lock(mMutex); | 
|  | 640 | if (!clientCacheId.isValid()) { | 
|  | 641 | ALOGE("invalid process, failed to erase buffer"); | 
|  | 642 | return; | 
|  | 643 | } | 
|  | 644 | eraseBufferLocked(clientCacheId); | 
|  | 645 | } | 
|  | 646 |  | 
|  | 647 | uint32_t BufferStateLayer::HwcSlotGenerator::getHwcCacheSlot(const client_cache_t& clientCacheId) { | 
|  | 648 | std::lock_guard<std::mutex> lock(mMutex); | 
|  | 649 | auto itr = mCachedBuffers.find(clientCacheId); | 
|  | 650 | if (itr == mCachedBuffers.end()) { | 
|  | 651 | return addCachedBuffer(clientCacheId); | 
|  | 652 | } | 
|  | 653 | auto& [hwcCacheSlot, counter] = itr->second; | 
|  | 654 | counter = mCounter++; | 
|  | 655 | return hwcCacheSlot; | 
|  | 656 | } | 
|  | 657 |  | 
|  | 658 | uint32_t BufferStateLayer::HwcSlotGenerator::addCachedBuffer(const client_cache_t& clientCacheId) | 
|  | 659 | REQUIRES(mMutex) { | 
|  | 660 | if (!clientCacheId.isValid()) { | 
|  | 661 | ALOGE("invalid process, returning invalid slot"); | 
|  | 662 | return BufferQueue::INVALID_BUFFER_SLOT; | 
|  | 663 | } | 
|  | 664 |  | 
|  | 665 | ClientCache::getInstance().registerErasedRecipient(clientCacheId, wp<ErasedRecipient>(this)); | 
|  | 666 |  | 
|  | 667 | uint32_t hwcCacheSlot = getFreeHwcCacheSlot(); | 
|  | 668 | mCachedBuffers[clientCacheId] = {hwcCacheSlot, mCounter++}; | 
|  | 669 | return hwcCacheSlot; | 
|  | 670 | } | 
|  | 671 |  | 
|  | 672 | uint32_t BufferStateLayer::HwcSlotGenerator::getFreeHwcCacheSlot() REQUIRES(mMutex) { | 
|  | 673 | if (mFreeHwcCacheSlots.empty()) { | 
|  | 674 | evictLeastRecentlyUsed(); | 
|  | 675 | } | 
|  | 676 |  | 
|  | 677 | uint32_t hwcCacheSlot = mFreeHwcCacheSlots.top(); | 
|  | 678 | mFreeHwcCacheSlots.pop(); | 
|  | 679 | return hwcCacheSlot; | 
|  | 680 | } | 
|  | 681 |  | 
|  | 682 | void BufferStateLayer::HwcSlotGenerator::evictLeastRecentlyUsed() REQUIRES(mMutex) { | 
|  | 683 | uint64_t minCounter = UINT_MAX; | 
|  | 684 | client_cache_t minClientCacheId = {}; | 
|  | 685 | for (const auto& [clientCacheId, slotCounter] : mCachedBuffers) { | 
|  | 686 | const auto& [hwcCacheSlot, counter] = slotCounter; | 
|  | 687 | if (counter < minCounter) { | 
|  | 688 | minCounter = counter; | 
|  | 689 | minClientCacheId = clientCacheId; | 
|  | 690 | } | 
|  | 691 | } | 
|  | 692 | eraseBufferLocked(minClientCacheId); | 
|  | 693 |  | 
|  | 694 | ClientCache::getInstance().unregisterErasedRecipient(minClientCacheId, this); | 
|  | 695 | } | 
|  | 696 |  | 
|  | 697 | void BufferStateLayer::HwcSlotGenerator::eraseBufferLocked(const client_cache_t& clientCacheId) | 
|  | 698 | REQUIRES(mMutex) { | 
|  | 699 | auto itr = mCachedBuffers.find(clientCacheId); | 
|  | 700 | if (itr == mCachedBuffers.end()) { | 
|  | 701 | return; | 
|  | 702 | } | 
|  | 703 | auto& [hwcCacheSlot, counter] = itr->second; | 
|  | 704 |  | 
|  | 705 | // TODO send to hwc cache and resources | 
|  | 706 |  | 
|  | 707 | mFreeHwcCacheSlots.push(hwcCacheSlot); | 
|  | 708 | mCachedBuffers.erase(clientCacheId); | 
|  | 709 | } | 
| Marissa Wall | 61c5862 | 2018-07-18 10:12:20 -0700 | [diff] [blame] | 710 | } // namespace android |