From dbbe3854efc2ceb6e0f5c2f0991161f6b7beea39 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Wed, 12 Jan 2022 20:22:11 -0800 Subject: SF: Make ExternalTexture mockable Expose GraphicBuffer properties via ExternalTexture class. Within SurfaceFlinger access the buffer via this proxy interface. This allows us to inject and mock GraphicBuffers as needed. Specifically this will be used to recreate layer state from transaction traces. Test: compiles Bug: 200284593 Change-Id: I2e7f6bee28314b70eac477cfadbf9f94c4d70339 --- services/surfaceflinger/SurfaceFlinger.cpp | 51 +++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 8 deletions(-) (limited to 'services/surfaceflinger/SurfaceFlinger.cpp') diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index bd13c4169c..1dc75c8f43 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -4419,10 +4420,13 @@ uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTime } } - if (what & layer_state_t::eBufferChanged && - layer->setBuffer(*s.bufferData, postTime, desiredPresentTime, isAutoTimestamp, - dequeueBufferTimestamp, frameTimelineInfo)) { - flags |= eTraversalNeeded; + if (what & layer_state_t::eBufferChanged) { + std::shared_ptr buffer = + getExternalTextureFromBufferData(*s.bufferData, layer->getDebugName()); + if (layer->setBuffer(buffer, *s.bufferData, postTime, desiredPresentTime, isAutoTimestamp, + dequeueBufferTimestamp, frameTimelineInfo)) { + flags |= eTraversalNeeded; + } } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) { layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime); } @@ -6384,9 +6388,10 @@ std::shared_future SurfaceFlinger::captureScre const status_t bufferStatus = buffer->initCheck(); LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureScreenCommon: Buffer failed to allocate: %d", bufferStatus); - const auto texture = std::make_shared< - renderengine::ExternalTexture>(buffer, getRenderEngine(), - renderengine::ExternalTexture::Usage::WRITEABLE); + const std::shared_ptr texture = std::make_shared< + renderengine::impl::ExternalTexture>(buffer, getRenderEngine(), + renderengine::impl::ExternalTexture::Usage:: + WRITEABLE); return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, texture, false /* regionSampling */, grayscale, captureListener); } @@ -6463,7 +6468,7 @@ std::shared_future SurfaceFlinger::renderScree captureResults.capturedSecureLayers || (layer->isVisible() && layer->isSecure()); }); - const bool useProtected = buffer->getBuffer()->getUsage() & GRALLOC_USAGE_PROTECTED; + const bool useProtected = buffer->getUsage() & GRALLOC_USAGE_PROTECTED; // We allow the system server to take screenshots of secure layers for // use in situations like the Screen-rotation animation and place @@ -7074,6 +7079,36 @@ status_t SurfaceFlinger::removeWindowInfosListener( return NO_ERROR; } +std::shared_ptr SurfaceFlinger::getExternalTextureFromBufferData( + const BufferData& bufferData, const char* layerName) const { + bool cacheIdChanged = bufferData.flags.test(BufferData::BufferDataChange::cachedBufferChanged); + bool bufferSizeExceedsLimit = false; + std::shared_ptr buffer = nullptr; + if (cacheIdChanged && bufferData.buffer != nullptr) { + bufferSizeExceedsLimit = exceedsMaxRenderTargetSize(bufferData.buffer->getWidth(), + bufferData.buffer->getHeight()); + if (!bufferSizeExceedsLimit) { + ClientCache::getInstance().add(bufferData.cachedBuffer, bufferData.buffer); + buffer = ClientCache::getInstance().get(bufferData.cachedBuffer); + } + } else if (cacheIdChanged) { + buffer = ClientCache::getInstance().get(bufferData.cachedBuffer); + } else if (bufferData.buffer != nullptr) { + bufferSizeExceedsLimit = exceedsMaxRenderTargetSize(bufferData.buffer->getWidth(), + bufferData.buffer->getHeight()); + if (!bufferSizeExceedsLimit) { + buffer = std::make_shared< + renderengine::impl::ExternalTexture>(bufferData.buffer, getRenderEngine(), + renderengine::impl::ExternalTexture:: + Usage::READABLE); + } + } + ALOGE_IF(bufferSizeExceedsLimit, + "Attempted to create an ExternalTexture for layer %s that exceeds render target size " + "limit.", + layerName); + return buffer; +} } // namespace android #if defined(__gl_h_) -- cgit v1.2.3-59-g8ed1b