diff options
Diffstat (limited to 'services/surfaceflinger/RefreshRateOverlay.cpp')
-rw-r--r-- | services/surfaceflinger/RefreshRateOverlay.cpp | 185 |
1 files changed, 57 insertions, 128 deletions
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp index 27a1c280fb..f602412930 100644 --- a/services/surfaceflinger/RefreshRateOverlay.cpp +++ b/services/surfaceflinger/RefreshRateOverlay.cpp @@ -17,9 +17,6 @@ // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" -#pragma clang diagnostic ignored "-Wextra" - -#include <algorithm> #include "RefreshRateOverlay.h" #include "Client.h" @@ -109,86 +106,52 @@ void RefreshRateOverlay::SevenSegmentDrawer::drawDigit(int digit, int left, cons drawSegment(Segment::Buttom, left, color, buffer, pixels); } -std::vector<sp<GraphicBuffer>> RefreshRateOverlay::SevenSegmentDrawer::drawNumber( - int number, const half4& color, bool showSpinner) { - if (number < 0 || number > 1000) return {}; +sp<GraphicBuffer> RefreshRateOverlay::SevenSegmentDrawer::drawNumber(int number, + const half4& color) { + if (number < 0 || number > 1000) return nullptr; const auto hundreds = number / 100; const auto tens = (number / 10) % 10; const auto ones = number % 10; - std::vector<sp<GraphicBuffer>> buffers; - const auto loopCount = showSpinner ? 6 : 1; - for (int i = 0; i < loopCount; i++) { - sp<GraphicBuffer> buffer = - new GraphicBuffer(BUFFER_WIDTH, BUFFER_HEIGHT, HAL_PIXEL_FORMAT_RGBA_8888, 1, - GRALLOC_USAGE_SW_WRITE_RARELY | GRALLOC_USAGE_HW_COMPOSER | - GRALLOC_USAGE_HW_TEXTURE, - "RefreshRateOverlayBuffer"); - const status_t bufferStatus = buffer->initCheck(); - LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "RefreshRateOverlay: Buffer failed to allocate: %d", - bufferStatus); - uint8_t* pixels; - buffer->lock(GRALLOC_USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&pixels)); - // Clear buffer content - drawRect(Rect(BUFFER_WIDTH, BUFFER_HEIGHT), half4(0), buffer, pixels); - int left = 0; - if (hundreds != 0) { - drawDigit(hundreds, left, color, buffer, pixels); - } - left += DIGIT_WIDTH + DIGIT_SPACE; - - if (tens != 0) { - drawDigit(tens, left, color, buffer, pixels); - } + sp<GraphicBuffer> buffer = + new GraphicBuffer(BUFFER_WIDTH, BUFFER_HEIGHT, HAL_PIXEL_FORMAT_RGBA_8888, 1, + GRALLOC_USAGE_SW_WRITE_RARELY | GRALLOC_USAGE_HW_COMPOSER | + GRALLOC_USAGE_HW_TEXTURE, + "RefreshRateOverlayBuffer"); + uint8_t* pixels; + buffer->lock(GRALLOC_USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&pixels)); + // Clear buffer content + drawRect(Rect(BUFFER_WIDTH, BUFFER_HEIGHT), half4(0), buffer, pixels); + int left = 0; + if (hundreds != 0) { + drawDigit(hundreds, left, color, buffer, pixels); left += DIGIT_WIDTH + DIGIT_SPACE; + } - drawDigit(ones, left, color, buffer, pixels); + if (tens != 0) { + drawDigit(tens, left, color, buffer, pixels); left += DIGIT_WIDTH + DIGIT_SPACE; - - if (showSpinner) { - switch (i) { - case 0: - drawSegment(Segment::Upper, left, color, buffer, pixels); - break; - case 1: - drawSegment(Segment::UpperRight, left, color, buffer, pixels); - break; - case 2: - drawSegment(Segment::LowerRight, left, color, buffer, pixels); - break; - case 3: - drawSegment(Segment::Buttom, left, color, buffer, pixels); - break; - case 4: - drawSegment(Segment::LowerLeft, left, color, buffer, pixels); - break; - case 5: - drawSegment(Segment::UpperLeft, left, color, buffer, pixels); - break; - } - } - - buffer->unlock(); - buffers.emplace_back(buffer); } - return buffers; + + drawDigit(ones, left, color, buffer, pixels); + buffer->unlock(); + return buffer; } -RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger, bool showSpinner) - : mFlinger(flinger), mClient(new Client(&mFlinger)), mShowSpinner(showSpinner) { +RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger) + : mFlinger(flinger), mClient(new Client(&mFlinger)) { createLayer(); - reset(); + primeCache(); } bool RefreshRateOverlay::createLayer() { - int32_t layerId; const status_t ret = mFlinger.createLayer(String8("RefreshRateOverlay"), mClient, SevenSegmentDrawer::getWidth(), SevenSegmentDrawer::getHeight(), PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceBufferState, LayerMetadata(), - &mIBinder, &mGbp, nullptr, &layerId); + &mIBinder, &mGbp, nullptr); if (ret) { ALOGE("failed to create buffer state layer"); return false; @@ -196,97 +159,63 @@ bool RefreshRateOverlay::createLayer() { Mutex::Autolock _l(mFlinger.mStateLock); mLayer = mClient->getLayerUser(mIBinder); - mLayer->setFrameRate(Layer::FrameRate(Fps(0.0f), Layer::FrameRateCompatibility::NoVote)); - mLayer->setIsAtRoot(true); + mLayer->setFrameRate(Layer::FrameRate(0, Layer::FrameRateCompatibility::NoVote)); // setting Layer's Z requires resorting layersSortedByZ - ssize_t idx = mFlinger.mDrawingState.layersSortedByZ.indexOf(mLayer); + ssize_t idx = mFlinger.mCurrentState.layersSortedByZ.indexOf(mLayer); if (mLayer->setLayer(INT32_MAX - 2) && idx >= 0) { - mFlinger.mDrawingState.layersSortedByZ.removeAt(idx); - mFlinger.mDrawingState.layersSortedByZ.add(mLayer); + mFlinger.mCurrentState.layersSortedByZ.removeAt(idx); + mFlinger.mCurrentState.layersSortedByZ.add(mLayer); } return true; } -const std::vector<std::shared_ptr<renderengine::ExternalTexture>>& -RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) { - if (mBufferCache.find(fps) == mBufferCache.end()) { - // Ensure the range is > 0, so we don't divide by 0. - const auto rangeLength = std::max(1u, mHighFps - mLowFps); - // Clip values outside the range [mLowFps, mHighFps]. The current fps may be outside - // of this range if the display has changed its set of supported refresh rates. - fps = std::max(fps, mLowFps); - fps = std::min(fps, mHighFps); - const auto fpsScale = static_cast<float>(fps - mLowFps) / rangeLength; +void RefreshRateOverlay::primeCache() { + auto& allRefreshRates = mFlinger.mRefreshRateConfigs->getAllRefreshRates(); + if (allRefreshRates.size() == 1) { + auto fps = allRefreshRates.begin()->second->getFps(); + half4 color = {LOW_FPS_COLOR, ALPHA}; + mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color)); + return; + } + + std::vector<uint32_t> supportedFps; + supportedFps.reserve(allRefreshRates.size()); + for (auto& [ignored, refreshRate] : allRefreshRates) { + supportedFps.push_back(refreshRate->getFps()); + } + + std::sort(supportedFps.begin(), supportedFps.end()); + const auto mLowFps = supportedFps[0]; + const auto mHighFps = supportedFps[supportedFps.size() - 1]; + for (auto fps : supportedFps) { + const auto fpsScale = float(fps - mLowFps) / (mHighFps - mLowFps); half4 color; color.r = HIGH_FPS_COLOR.r * fpsScale + LOW_FPS_COLOR.r * (1 - fpsScale); color.g = HIGH_FPS_COLOR.g * fpsScale + LOW_FPS_COLOR.g * (1 - fpsScale); color.b = HIGH_FPS_COLOR.b * fpsScale + LOW_FPS_COLOR.b * (1 - fpsScale); color.a = ALPHA; - auto buffers = SevenSegmentDrawer::drawNumber(fps, color, mShowSpinner); - std::vector<std::shared_ptr<renderengine::ExternalTexture>> textures; - std::transform(buffers.begin(), buffers.end(), std::back_inserter(textures), - [&](const auto& buffer) -> std::shared_ptr<renderengine::ExternalTexture> { - return std::make_shared< - renderengine::ExternalTexture>(buffer, - mFlinger.getRenderEngine(), - renderengine::ExternalTexture:: - Usage::READABLE); - }); - mBufferCache.emplace(fps, textures); + mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color)); } - - return mBufferCache[fps]; } void RefreshRateOverlay::setViewport(ui::Size viewport) { - Rect frame((3 * viewport.width) >> 4, viewport.height >> 5); + Rect frame(viewport.width >> 3, viewport.height >> 5); frame.offsetBy(viewport.width >> 5, viewport.height >> 4); + mLayer->setFrame(frame); - layer_state_t::matrix22_t matrix; - matrix.dsdx = frame.getWidth() / static_cast<float>(SevenSegmentDrawer::getWidth()); - matrix.dtdx = 0; - matrix.dtdy = 0; - matrix.dsdy = frame.getHeight() / static_cast<float>(SevenSegmentDrawer::getHeight()); - mLayer->setMatrix(matrix, true); - mLayer->setPosition(frame.left, frame.top); mFlinger.mTransactionFlags.fetch_or(eTransactionMask); } -void RefreshRateOverlay::changeRefreshRate(const Fps& fps) { - mCurrentFps = fps.getIntValue(); - auto buffer = getOrCreateBuffers(*mCurrentFps)[mFrame]; - mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, true, {}, - mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */), - std::nullopt /* dequeueTime */, FrameTimelineInfo{}, - nullptr /* releaseBufferListener */); +void RefreshRateOverlay::changeRefreshRate(const RefreshRate& refreshRate) { + auto buffer = mBufferCache[refreshRate.getFps()]; + mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {}); mFlinger.mTransactionFlags.fetch_or(eTransactionMask); } -void RefreshRateOverlay::onInvalidate() { - if (!mCurrentFps.has_value()) return; - - const auto& buffers = getOrCreateBuffers(*mCurrentFps); - mFrame = (mFrame + 1) % buffers.size(); - auto buffer = buffers[mFrame]; - mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, true, {}, - mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */), - std::nullopt /* dequeueTime */, FrameTimelineInfo{}, - nullptr /* releaseBufferListener */); - - mFlinger.mTransactionFlags.fetch_or(eTransactionMask); -} - -void RefreshRateOverlay::reset() { - mBufferCache.clear(); - const auto range = mFlinger.mRefreshRateConfigs->getSupportedRefreshRateRange(); - mLowFps = range.min.getIntValue(); - mHighFps = range.max.getIntValue(); -} - } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wconversion -Wextra" +#pragma clang diagnostic pop // ignored "-Wconversion" |