summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
author Alec Mouri <alecmouri@google.com> 2021-04-02 16:29:27 -0700
committer Alec Mouri <alecmouri@google.com> 2021-04-13 11:07:37 -0700
commit2daef3c6ba72f364f9ac3859efc1cf2782fff67f (patch)
tree7ccb72649ff6fa7dcaa19aa42e0d7195a5b9def3 /services/surfaceflinger/SurfaceFlinger.cpp
parentf9932d790474fcf3f10c2085d18f86e672ebec54 (diff)
Add ExternalTexture class into RenderEngine interface
ExternalTexture is an RAII structure that wraps raw GraphicBuffers that are passed into RenderEngine. ExternalTexture's role is to help with managing GPU resources of GraphicBuffers by mapping buffers into textures, EGLImages, or AutoBackendTextures depending on the RenderEngine backend. Under the hood, mapExternalTextureBuffer and unmapExternalTextureBuffer (renamed from cacheExternalTextureBuffer and unbindExternalTextureBuffer respectively) are used to help tie resource management to the ExternalTexture lifetime. The main motivation for this is that currently managing buffer lifecycle has historically been errorprone and caused memory leaks, so this improves code health. As part of this: * mapExternalTextureBuffer and unmapExternalTextureBuffer are now protected methods, and are never called outside of RenderEngine with the exception of creating and destroying ExternalTextures. * Because GLESRenderEngine's output buffers are cached differently from Skia RenderEngine, if there are output-only buffers then disable the mapExternalTextureBuffer calls whenever GLESRenderEngine is used. * Custom RAII classes in the Planner and in BufferLayerConsumer are now removed since they're subsumed by ExternalTexture * RenderSurface now controls its own management of ExternalTextures in a small queue * cleanFramebufferCache is now unimplemented for Skia, because ExternalTextures are now deleted whenever a RenderSurface is deleted. Bug: 180767535 Test: libsurfaceflinger_unittest Test: libcompositionengine_test Test: librenderengine_test Test: Simulate virtual displays Test: Screen reotation Test: Movie playback on Google TV Test: Force GPU composition Test: screenshot Change-Id: I222c71e6e1c67485cdeac49e2cb829289af9efec
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp67
1 files changed, 23 insertions, 44 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 02579c6bde..e66f65b71e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -735,6 +735,7 @@ void SurfaceFlinger::init() {
mCompositionEngine->setTimeStats(mTimeStats);
mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
mCompositionEngine->getHwComposer().setConfiguration(this, getBE().mComposerSequenceId);
+ ClientCache::getInstance().setRenderEngine(&getRenderEngine());
// Process any initial hotplug and resulting display changes.
processDisplayHotplugEventsLocked();
const auto display = getDefaultDisplayDeviceLocked();
@@ -3707,7 +3708,6 @@ void SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin
if (uncacheBuffer.isValid()) {
ClientCache::getInstance().erase(uncacheBuffer);
- getRenderEngine().unbindExternalTextureBuffer(uncacheBuffer.id);
}
// If a synchronous transaction is explicitly requested without any changes, force a transaction
@@ -4083,23 +4083,16 @@ uint32_t SurfaceFlinger::setClientStateLocked(
}
bool bufferChanged = what & layer_state_t::eBufferChanged;
bool cacheIdChanged = what & layer_state_t::eCachedBufferChanged;
- sp<GraphicBuffer> buffer;
+ std::shared_ptr<renderengine::ExternalTexture> buffer;
if (bufferChanged && cacheIdChanged && s.buffer != nullptr) {
- buffer = s.buffer;
- bool success = ClientCache::getInstance().add(s.cachedBuffer, s.buffer);
- if (success) {
- getRenderEngine().cacheExternalTextureBuffer(s.buffer);
- success = ClientCache::getInstance()
- .registerErasedRecipient(s.cachedBuffer,
- wp<ClientCache::ErasedRecipient>(this));
- if (!success) {
- getRenderEngine().unbindExternalTextureBuffer(s.buffer->getId());
- }
- }
+ ClientCache::getInstance().add(s.cachedBuffer, s.buffer);
+ buffer = ClientCache::getInstance().get(s.cachedBuffer);
} else if (cacheIdChanged) {
buffer = ClientCache::getInstance().get(s.cachedBuffer);
} else if (bufferChanged) {
- buffer = s.buffer;
+ buffer = std::make_shared<
+ renderengine::ExternalTexture>(s.buffer, getRenderEngine(),
+ renderengine::ExternalTexture::Usage::READABLE);
}
if (buffer) {
const bool frameNumberChanged = what & layer_state_t::eFrameNumberChanged;
@@ -6003,15 +5996,17 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
const status_t bufferStatus = buffer->initCheck();
LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureScreenCommon: Buffer failed to allocate: %d",
bufferStatus);
- return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer,
+ const auto texture = std::make_shared<
+ renderengine::ExternalTexture>(buffer, getRenderEngine(),
+ renderengine::ExternalTexture::Usage::WRITEABLE);
+ return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, texture,
false /* regionSampling */, grayscale, captureListener);
}
-status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
- TraverseLayersFunction traverseLayers,
- sp<GraphicBuffer>& buffer, bool regionSampling,
- bool grayscale,
- const sp<IScreenCaptureListener>& captureListener) {
+status_t SurfaceFlinger::captureScreenCommon(
+ RenderAreaFuture renderAreaFuture, TraverseLayersFunction traverseLayers,
+ const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
+ bool grayscale, const sp<IScreenCaptureListener>& captureListener) {
ATRACE_CALL();
if (captureListener == nullptr) {
@@ -6044,15 +6039,6 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
regionSampling, grayscale, captureResults);
});
- // TODO(b/180767535): Remove this once we optimize buffer lifecycle for RenderEngine
- // Only do this when we're not doing region sampling, to allow the region sampling thread to
- // manage buffer lifecycle itself.
- if (!regionSampling &&
- getRenderEngine().getRenderEngineType() ==
- renderengine::RenderEngine::RenderEngineType::SKIA_GL_THREADED) {
- getRenderEngine().unbindExternalTextureBuffer(buffer->getId());
- }
-
captureResults.result = result;
captureListener->onScreenCaptureCompleted(captureResults);
}));
@@ -6060,11 +6046,10 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
return NO_ERROR;
}
-status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
- TraverseLayersFunction traverseLayers,
- const sp<GraphicBuffer>& buffer, bool forSystem,
- bool regionSampling, bool grayscale,
- ScreenCaptureResults& captureResults) {
+status_t SurfaceFlinger::renderScreenImplLocked(
+ const RenderArea& renderArea, TraverseLayersFunction traverseLayers,
+ const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool forSystem,
+ bool regionSampling, bool grayscale, ScreenCaptureResults& captureResults) {
ATRACE_CALL();
traverseLayers([&](Layer* layer) {
@@ -6072,7 +6057,7 @@ status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
captureResults.capturedSecureLayers || (layer->isVisible() && layer->isSecure());
});
- const bool useProtected = buffer->getUsage() & GRALLOC_USAGE_PROTECTED;
+ const bool useProtected = buffer->getBuffer()->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
@@ -6082,7 +6067,7 @@ status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
return PERMISSION_DENIED;
}
- captureResults.buffer = buffer;
+ captureResults.buffer = buffer->getBuffer();
captureResults.capturedDataspace = renderArea.getReqDataSpace();
const auto reqWidth = renderArea.getReqWidth();
@@ -6173,11 +6158,9 @@ status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
base::unique_fd drawFence;
getRenderEngine().useProtectedContext(useProtected);
- // TODO(b/180767535): Remove this once we optimize buffer lifecycle for RenderEngine
- const bool useFramebufferCache = getRenderEngine().getRenderEngineType() ==
- renderengine::RenderEngine::RenderEngineType::SKIA_GL_THREADED;
+ const constexpr bool kUseFramebufferCache = false;
getRenderEngine().drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, buffer,
- useFramebufferCache, std::move(bufferFence), &drawFence);
+ kUseFramebufferCache, std::move(bufferFence), &drawFence);
if (drawFence >= 0) {
sp<Fence> releaseFence = new Fence(dup(drawFence));
@@ -6442,10 +6425,6 @@ void SurfaceFlinger::removeFromOffscreenLayers(Layer* layer) {
mOffscreenLayers.erase(layer);
}
-void SurfaceFlinger::bufferErased(const client_cache_t& clientCacheId) {
- getRenderEngine().unbindExternalTextureBuffer(clientCacheId.id);
-}
-
status_t SurfaceFlinger::setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
float lightPosY, float lightPosZ,
float lightRadius) {