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
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
index f680460..daee83b 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h
@@ -16,15 +16,16 @@
#pragma once
-#include <cstdint>
-#include <vector>
-
+#include <renderengine/ExternalTexture.h>
#include <ui/Fence.h>
#include <ui/GraphicTypes.h>
#include <ui/Size.h>
#include <utils/Errors.h>
#include <utils/StrongPointer.h>
+#include <cstdint>
+#include <vector>
+
namespace android {
class GraphicBuffer;
@@ -80,7 +81,8 @@
virtual void prepareFrame(bool usesClientComposition, bool usesDeviceComposition) = 0;
// Allocates a buffer as scratch space for GPU composition
- virtual sp<GraphicBuffer> dequeueBuffer(base::unique_fd* bufferFence) = 0;
+ virtual std::shared_ptr<renderengine::ExternalTexture> dequeueBuffer(
+ base::unique_fd* bufferFence) = 0;
// Queues the drawn buffer for consumption by HWC. readyFence is the fence
// which will fire when the buffer is ready for consumption.
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h
index a1230b3..a8d372c 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h
@@ -45,6 +45,8 @@
// The DisplaySurface for this surface
sp<DisplaySurface> displaySurface;
+
+ size_t maxTextureCacheSize;
};
/**
@@ -81,6 +83,11 @@
return *this;
}
+ RenderSurfaceCreationArgsBuilder& setMaxTextureCacheSize(size_t maxTextureCacheSize) {
+ mArgs.maxTextureCacheSize = maxTextureCacheSize;
+ return *this;
+ }
+
private:
RenderSurfaceCreationArgs mArgs;
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
index 48a54d6..c61ec59 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -18,7 +18,7 @@
#include <compositionengine/ProjectionSpace.h>
#include <compositionengine/impl/HwcBufferCache.h>
-#include <renderengine/Mesh.h>
+#include <renderengine/ExternalTexture.h>
#include <ui/FloatRect.h>
#include <ui/GraphicTypes.h>
#include <ui/Rect.h>
@@ -89,7 +89,7 @@
// Overrides the buffer, acquire fence, and display frame stored in LayerFECompositionState
struct {
- sp<GraphicBuffer> buffer = nullptr;
+ std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr;
sp<Fence> acquireFence = nullptr;
Rect displayFrame = {};
ui::Dataspace dataspace{ui::Dataspace::UNKNOWN};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
index 5127a6f..a8a5380 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h
@@ -16,12 +16,16 @@
#pragma once
-#include <memory>
-
#include <android-base/unique_fd.h>
#include <compositionengine/RenderSurface.h>
#include <utils/StrongPointer.h>
+#include <memory>
+#include <vector>
+
+#include "renderengine/ExternalTexture.h"
+#include "renderengine/RenderEngine.h"
+
struct ANativeWindow;
namespace android {
@@ -54,7 +58,8 @@
void setProtected(bool useProtected) override;
status_t beginFrame(bool mustRecompose) override;
void prepareFrame(bool usesClientComposition, bool usesDeviceComposition) override;
- sp<GraphicBuffer> dequeueBuffer(base::unique_fd* bufferFence) override;
+ std::shared_ptr<renderengine::ExternalTexture> dequeueBuffer(
+ base::unique_fd* bufferFence) override;
void queueBuffer(base::unique_fd readyFence) override;
void onPresentDisplayCompleted() override;
void flip() override;
@@ -66,7 +71,7 @@
// Testing
void setPageFlipCountForTest(std::uint32_t);
void setSizeForTest(const ui::Size&);
- sp<GraphicBuffer>& mutableGraphicBufferForTest();
+ std::shared_ptr<renderengine::ExternalTexture>& mutableTextureForTest();
base::unique_fd& mutableBufferReadyForTest();
private:
@@ -75,10 +80,13 @@
// ANativeWindow being rendered into
const sp<ANativeWindow> mNativeWindow;
- // Current buffer being rendered into
- sp<GraphicBuffer> mGraphicBuffer;
+
+ std::vector<std::shared_ptr<renderengine::ExternalTexture>> mTextureCache;
+ // Current texture being rendered into
+ std::shared_ptr<renderengine::ExternalTexture> mTexture;
const sp<DisplaySurface> mDisplaySurface;
ui::Size mSize;
+ const size_t mMaxTextureCacheSize;
bool mProtected{false};
std::uint32_t mPageFlipCount{0};
};
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
index c5d03a7..53f4a30 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h
@@ -66,7 +66,7 @@
const Rect& getBounds() const { return mBounds; }
const Region& getVisibleRegion() const { return mVisibleRegion; }
size_t getAge() const { return mAge; }
- const sp<GraphicBuffer>& getBuffer() const { return mTexture.getBuffer(); }
+ const std::shared_ptr<renderengine::ExternalTexture>& getBuffer() const { return mTexture; }
const sp<Fence>& getDrawFence() const { return mDrawFence; }
const ProjectionSpace& getOutputSpace() const { return mOutputSpace; }
ui::Dataspace getOutputDataspace() const { return mOutputDataspace; }
@@ -87,7 +87,7 @@
void setLastUpdate(std::chrono::steady_clock::time_point now) { mLastUpdate = now; }
void append(const CachedSet& other) {
- mTexture.setBuffer(nullptr, nullptr);
+ mTexture = nullptr;
mOutputDataspace = ui::Dataspace::UNKNOWN;
mDrawFence = nullptr;
@@ -115,31 +115,7 @@
Region mVisibleRegion;
size_t mAge = 0;
- class Texture {
- public:
- ~Texture() { setBuffer(nullptr, nullptr); }
-
- void setBuffer(const sp<GraphicBuffer>& buffer, renderengine::RenderEngine* re) {
- if (mRE && mBuffer) {
- mRE->unbindExternalTextureBuffer(mBuffer->getId());
- }
-
- mBuffer = buffer;
- mRE = re;
-
- if (mRE && mBuffer) {
- mRE->cacheExternalTextureBuffer(mBuffer);
- }
- }
-
- const sp<GraphicBuffer>& getBuffer() const { return mBuffer; }
-
- private:
- sp<GraphicBuffer> mBuffer = nullptr;
- renderengine::RenderEngine* mRE = nullptr;
- };
-
- Texture mTexture;
+ std::shared_ptr<renderengine::ExternalTexture> mTexture;
sp<Fence> mDrawFence;
ProjectionSpace mOutputSpace;
ui::Dataspace mOutputDataspace;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
index a0cae6f..fe858c2 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h
@@ -39,7 +39,7 @@
MOCK_METHOD1(setBufferPixelFormat, void(ui::PixelFormat));
MOCK_METHOD1(beginFrame, status_t(bool mustRecompose));
MOCK_METHOD2(prepareFrame, void(bool, bool));
- MOCK_METHOD1(dequeueBuffer, sp<GraphicBuffer>(base::unique_fd*));
+ MOCK_METHOD1(dequeueBuffer, std::shared_ptr<renderengine::ExternalTexture>(base::unique_fd*));
MOCK_METHOD1(queueBuffer, void(base::unique_fd));
MOCK_METHOD0(onPresentDisplayCompleted, void());
MOCK_METHOD0(flip, void());
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 3ac5433..3468b20 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#include <thread>
-
+#include <SurfaceFlingerProperties.sysprop.h>
#include <android-base/stringprintf.h>
#include <compositionengine/CompositionEngine.h>
#include <compositionengine/CompositionRefreshArgs.h>
@@ -29,7 +28,9 @@
#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <compositionengine/impl/planner/Planner.h>
-#include <SurfaceFlingerProperties.sysprop.h>
+#include <thread>
+
+#include "renderengine/ExternalTexture.h"
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
@@ -715,11 +716,11 @@
bool skipLayer = false;
if (layer->getState().overrideInfo.buffer != nullptr) {
if (previousOverride != nullptr &&
- layer->getState().overrideInfo.buffer == previousOverride) {
+ layer->getState().overrideInfo.buffer->getBuffer() == previousOverride) {
ALOGV("Skipping redundant buffer");
skipLayer = true;
}
- previousOverride = layer->getState().overrideInfo.buffer;
+ previousOverride = layer->getState().overrideInfo.buffer->getBuffer();
}
const bool includeGeometry = refreshArgs.updatingGeometryThisFrame;
@@ -978,14 +979,15 @@
}
base::unique_fd fd;
- sp<GraphicBuffer> buf;
+
+ std::shared_ptr<renderengine::ExternalTexture> tex;
// If we aren't doing client composition on this output, but do have a
// flipClientTarget request for this frame on this output, we still need to
// dequeue a buffer.
if (hasClientComposition || outputState.flipClientTarget) {
- buf = mRenderSurface->dequeueBuffer(&fd);
- if (buf == nullptr) {
+ tex = mRenderSurface->dequeueBuffer(&fd);
+ if (tex == nullptr) {
ALOGW("Dequeuing buffer for display [%s] failed, bailing out of "
"client composition for this frame",
mName.c_str());
@@ -1030,13 +1032,14 @@
// Check if the client composition requests were rendered into the provided graphic buffer. If
// so, we can reuse the buffer and avoid client composition.
if (mClientCompositionRequestCache) {
- if (mClientCompositionRequestCache->exists(buf->getId(), clientCompositionDisplay,
+ if (mClientCompositionRequestCache->exists(tex->getBuffer()->getId(),
+ clientCompositionDisplay,
clientCompositionLayers)) {
outputCompositionState.reusedClientComposition = true;
setExpensiveRenderingExpected(false);
return readyFence;
}
- mClientCompositionRequestCache->add(buf->getId(), clientCompositionDisplay,
+ mClientCompositionRequestCache->add(tex->getBuffer()->getId(), clientCompositionDisplay,
clientCompositionLayers);
}
@@ -1069,12 +1072,12 @@
// over to RenderEngine, in which case this flag can be removed from the drawLayers interface.
const bool useFramebufferCache = outputState.layerStackInternal;
status_t status =
- renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, buf,
+ renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, tex,
useFramebufferCache, std::move(fd), &readyFence);
if (status != NO_ERROR && mClientCompositionRequestCache) {
// If rendering was not successful, remove the request from the cache.
- mClientCompositionRequestCache->remove(buf->getId());
+ mClientCompositionRequestCache->remove(tex->getBuffer()->getId());
}
auto& timeStats = getCompositionEngine().getTimeStats();
@@ -1151,9 +1154,9 @@
std::vector<LayerFE::LayerSettings> results;
if (layer->getState().overrideInfo.buffer != nullptr) {
- if (layer->getState().overrideInfo.buffer != previousOverrideBuffer) {
+ if (layer->getState().overrideInfo.buffer->getBuffer() != previousOverrideBuffer) {
results = layer->getOverrideCompositionList();
- previousOverrideBuffer = layer->getState().overrideInfo.buffer;
+ previousOverrideBuffer = layer->getState().overrideInfo.buffer->getBuffer();
ALOGV("Replacing [%s] with override in RE", layer->getLayerFE().getDebugName());
} else {
ALOGV("Skipping redundant override buffer for [%s] in RE",
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index f640f85..9ca8914 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -537,7 +537,7 @@
sp<GraphicBuffer> buffer = outputIndependentState.buffer;
sp<Fence> acquireFence = outputIndependentState.acquireFence;
if (getState().overrideInfo.buffer != nullptr) {
- buffer = getState().overrideInfo.buffer;
+ buffer = getState().overrideInfo.buffer->getBuffer();
acquireFence = getState().overrideInfo.acquireFence;
}
@@ -699,7 +699,7 @@
settings.geometry = renderengine::Geometry{
.boundaries = boundaries.toFloatRect(),
};
- settings.bufferId = getState().overrideInfo.buffer->getId();
+ settings.bufferId = getState().overrideInfo.buffer->getBuffer()->getId();
settings.source = renderengine::PixelSource{
.buffer = renderengine::Buffer{
.buffer = getState().overrideInfo.buffer,
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index 3bef77d..ef50870 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -25,8 +25,8 @@
#include <compositionengine/impl/DumpHelpers.h>
#include <compositionengine/impl/OutputCompositionState.h>
#include <compositionengine/impl/RenderSurface.h>
-
#include <log/log.h>
+#include <renderengine/ExternalTexture.h>
#include <renderengine/RenderEngine.h>
#include <system/window.h>
#include <ui/GraphicBuffer.h>
@@ -63,7 +63,8 @@
mDisplay(display),
mNativeWindow(args.nativeWindow),
mDisplaySurface(args.displaySurface),
- mSize(args.displayWidth, args.displayHeight) {
+ mSize(args.displayWidth, args.displayHeight),
+ mMaxTextureCacheSize(args.maxTextureCacheSize) {
LOG_ALWAYS_FATAL_IF(!mNativeWindow);
}
@@ -146,7 +147,8 @@
}
}
-sp<GraphicBuffer> RenderSurface::dequeueBuffer(base::unique_fd* bufferFence) {
+std::shared_ptr<renderengine::ExternalTexture> RenderSurface::dequeueBuffer(
+ base::unique_fd* bufferFence) {
ATRACE_CALL();
int fd = -1;
ANativeWindowBuffer* buffer = nullptr;
@@ -158,16 +160,41 @@
mDisplay.getName().c_str(), result);
// Return fast here as we can't do much more - any rendering we do
// now will just be wrong.
- return mGraphicBuffer;
+ return mTexture;
}
- ALOGW_IF(mGraphicBuffer != nullptr, "Clobbering a non-null pointer to a buffer [%p].",
- mGraphicBuffer->getNativeBuffer()->handle);
- mGraphicBuffer = GraphicBuffer::from(buffer);
+ ALOGW_IF(mTexture != nullptr, "Clobbering a non-null pointer to a buffer [%p].",
+ mTexture->getBuffer()->getNativeBuffer()->handle);
+
+ sp<GraphicBuffer> newBuffer = GraphicBuffer::from(buffer);
+
+ std::shared_ptr<renderengine::ExternalTexture> texture;
+
+ for (auto it = mTextureCache.begin(); it != mTextureCache.end(); it++) {
+ const auto& cachedTexture = *it;
+ if (cachedTexture->getBuffer()->getId() == newBuffer->getId()) {
+ texture = cachedTexture;
+ mTextureCache.erase(it);
+ break;
+ }
+ }
+
+ if (texture) {
+ mTexture = texture;
+ } else {
+ mTexture = std::make_shared<
+ renderengine::ExternalTexture>(GraphicBuffer::from(buffer),
+ mCompositionEngine.getRenderEngine(),
+ renderengine::ExternalTexture::Usage::WRITEABLE);
+ }
+ mTextureCache.push_back(mTexture);
+ if (mTextureCache.size() > mMaxTextureCacheSize) {
+ mTextureCache.erase(mTextureCache.begin());
+ }
*bufferFence = base::unique_fd(fd);
- return mGraphicBuffer;
+ return mTexture;
}
void RenderSurface::queueBuffer(base::unique_fd readyFence) {
@@ -177,24 +204,24 @@
// hasFlipClientTargetRequest could return true even if we haven't
// dequeued a buffer before. Try dequeueing one if we don't have a
// buffer ready.
- if (mGraphicBuffer == nullptr) {
+ if (mTexture == nullptr) {
ALOGI("Attempting to queue a client composited buffer without one "
"previously dequeued for display [%s]. Attempting to dequeue "
"a scratch buffer now",
mDisplay.getName().c_str());
- // We shouldn't deadlock here, since mGraphicBuffer == nullptr only
+ // We shouldn't deadlock here, since mTexture == nullptr only
// after a successful call to queueBuffer, or if dequeueBuffer has
// never been called.
base::unique_fd unused;
dequeueBuffer(&unused);
}
- if (mGraphicBuffer == nullptr) {
+ if (mTexture == nullptr) {
ALOGE("No buffer is ready for display [%s]", mDisplay.getName().c_str());
} else {
- status_t result =
- mNativeWindow->queueBuffer(mNativeWindow.get(),
- mGraphicBuffer->getNativeBuffer(), dup(readyFence));
+ status_t result = mNativeWindow->queueBuffer(mNativeWindow.get(),
+ mTexture->getBuffer()->getNativeBuffer(),
+ dup(readyFence));
if (result != NO_ERROR) {
ALOGE("Error when queueing buffer for display [%s]: %d", mDisplay.getName().c_str(),
result);
@@ -204,11 +231,12 @@
LOG_ALWAYS_FATAL("ANativeWindow::queueBuffer failed with error: %d", result);
} else {
mNativeWindow->cancelBuffer(mNativeWindow.get(),
- mGraphicBuffer->getNativeBuffer(), dup(readyFence));
+ mTexture->getBuffer()->getNativeBuffer(),
+ dup(readyFence));
}
}
- mGraphicBuffer = nullptr;
+ mTexture = nullptr;
}
}
@@ -256,8 +284,8 @@
mSize = size;
}
-sp<GraphicBuffer>& RenderSurface::mutableGraphicBufferForTest() {
- return mGraphicBuffer;
+std::shared_ptr<renderengine::ExternalTexture>& RenderSurface::mutableTextureForTest() {
+ return mTexture;
}
} // namespace impl
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index dcb7555..53557bb 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -130,7 +130,7 @@
}
bool CachedSet::hasReadyBuffer() const {
- return mTexture.getBuffer() != nullptr && mDrawFence->getStatus() == Fence::Status::Signaled;
+ return mTexture != nullptr && mDrawFence->getStatus() == Fence::Status::Signaled;
}
std::vector<CachedSet> CachedSet::decompose() const {
@@ -217,21 +217,27 @@
sp<GraphicBuffer> buffer = new GraphicBuffer(static_cast<uint32_t>(mBounds.getWidth()),
static_cast<uint32_t>(mBounds.getHeight()),
HAL_PIXEL_FORMAT_RGBA_8888, 1, usageFlags);
+ const auto texture = std::make_shared<
+ renderengine::ExternalTexture>(buffer, renderEngine,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::WRITEABLE);
LOG_ALWAYS_FATAL_IF(buffer->initCheck() != OK);
base::unique_fd drawFence;
- status_t result = renderEngine.drawLayers(displaySettings, layerSettingsPointers, buffer, false,
- base::unique_fd(), &drawFence);
+ status_t result = renderEngine.drawLayers(displaySettings, layerSettingsPointers, mTexture,
+ false, base::unique_fd(), &drawFence);
if (result == NO_ERROR) {
- mTexture.setBuffer(buffer, &renderEngine);
mDrawFence = new Fence(drawFence.release());
mOutputSpace = ProjectionSpace(ui::Size(outputState.framebufferSpace.bounds.getWidth(),
outputState.framebufferSpace.bounds.getHeight()),
mBounds);
+ mTexture = std::move(texture);
mOutputSpace.orientation = outputState.framebufferSpace.orientation;
mOutputDataspace = outputDataspace;
mOrientation = orientation;
+ } else {
+ mTexture = nullptr;
}
}
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
index ad75557..3a2534b 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
@@ -111,7 +111,12 @@
const GraphicBuffer* currentOverrideBuffer = nullptr;
bool hasSkippedLayers = false;
for (auto layer : layers) {
- const GraphicBuffer* overrideBuffer = layer->getState().overrideInfo.buffer.get();
+ if (!layer->getState().overrideInfo.buffer) {
+ continue;
+ }
+
+ const GraphicBuffer* overrideBuffer =
+ layer->getState().overrideInfo.buffer->getBuffer().get();
if (overrideBuffer != nullptr && overrideBuffer == currentOverrideBuffer) {
// Skip this layer since it is part of a previous cached set
hasSkippedLayers = true;
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 8a4d161..4c3f494 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -26,6 +26,7 @@
#include "MockHWC2.h"
#include "MockHWComposer.h"
#include "RegionMatcher.h"
+#include "renderengine/mock/RenderEngine.h"
namespace android::compositionengine {
namespace {
@@ -715,7 +716,7 @@
static const HdrMetadata kHdrMetadata;
static native_handle_t* kSidebandStreamHandle;
static const sp<GraphicBuffer> kBuffer;
- static const sp<GraphicBuffer> kOverrideBuffer;
+ std::shared_ptr<renderengine::ExternalTexture> kOverrideBuffer;
static const sp<Fence> kFence;
static const sp<Fence> kOverrideFence;
static const std::string kLayerGenericMetadata1Key;
@@ -724,6 +725,11 @@
static const std::vector<uint8_t> kLayerGenericMetadata2Value;
OutputLayerWriteStateToHWCTest() {
+ kOverrideBuffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::
+ WRITEABLE);
auto& outputLayerState = mOutputLayer.editState();
outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer);
@@ -839,6 +845,7 @@
std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()};
StrictMock<mock::DisplayColorProfile> mDisplayColorProfile;
+ renderengine::mock::RenderEngine mRenderEngine;
};
const half4 OutputLayerWriteStateToHWCTest::kColor{81.f / 255.f, 82.f / 255.f, 83.f / 255.f,
@@ -858,7 +865,6 @@
native_handle_t* OutputLayerWriteStateToHWCTest::kSidebandStreamHandle =
reinterpret_cast<native_handle_t*>(1031);
const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kBuffer;
-const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kOverrideBuffer = new GraphicBuffer();
const sp<Fence> OutputLayerWriteStateToHWCTest::kFence;
const sp<Fence> OutputLayerWriteStateToHWCTest::kOverrideFence = new Fence();
const std::string OutputLayerWriteStateToHWCTest::kLayerGenericMetadata1Key =
@@ -1023,7 +1029,7 @@
kOverrideBufferTransform, kOverrideBlendMode, kOverrideAlpha);
expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
kOverrideSurfaceDamage);
- expectSetHdrMetadataAndBufferCalls(kOverrideBuffer, kOverrideFence);
+ expectSetHdrMetadataAndBufferCalls(kOverrideBuffer->getBuffer(), kOverrideFence);
expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false);
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 5f0b0ee..e80100c 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#include <cmath>
-
#include <android-base/stringprintf.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/impl/Output.h>
@@ -31,9 +29,12 @@
#include <ui/Rect.h>
#include <ui/Region.h>
+#include <cmath>
+
#include "CallOrderStateMachineHelper.h"
#include "MockHWC2.h"
#include "RegionMatcher.h"
+#include "renderengine/ExternalTexture.h"
namespace android::compositionengine {
namespace {
@@ -2960,7 +2961,10 @@
mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
StrictMock<OutputPartialMock> mOutput;
- sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
+ std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::WRITEABLE);
std::optional<base::unique_fd> mReadyFence;
};
@@ -3173,7 +3177,10 @@
EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
.WillRepeatedly(Return());
- sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
+ const auto otherOutputBuffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::WRITEABLE);
EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
.WillOnce(Return(mOutputBuffer))
.WillOnce(Return(otherOutputBuffer));
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index 5ef5d7b..9aeb290 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -15,6 +15,8 @@
*/
// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#include "renderengine/ExternalTexture.h"
+#include "ui/GraphicBuffer.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wextra"
@@ -239,9 +241,9 @@
DoAll(SetArgPointee<0>(buffer.get()), SetArgPointee<1>(-1), Return(NO_ERROR)));
base::unique_fd fence;
- EXPECT_EQ(buffer.get(), mSurface.dequeueBuffer(&fence).get());
+ EXPECT_EQ(buffer.get(), mSurface.dequeueBuffer(&fence)->getBuffer().get());
- EXPECT_EQ(buffer.get(), mSurface.mutableGraphicBufferForTest().get());
+ EXPECT_EQ(buffer.get(), mSurface.mutableTextureForTest()->getBuffer().get());
}
/*
@@ -249,8 +251,11 @@
*/
TEST_F(RenderSurfaceTest, queueBufferHandlesNoClientComposition) {
- sp<GraphicBuffer> buffer = new GraphicBuffer();
- mSurface.mutableGraphicBufferForTest() = buffer;
+ const auto buffer = std::make_shared<
+ renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
+ renderengine::ExternalTexture::Usage::READABLE |
+ renderengine::ExternalTexture::Usage::WRITEABLE);
+ mSurface.mutableTextureForTest() = buffer;
impl::OutputCompositionState state;
state.usesClientComposition = false;
@@ -261,43 +266,45 @@
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(buffer.get(), mSurface.mutableGraphicBufferForTest().get());
+ EXPECT_EQ(buffer.get(), mSurface.mutableTextureForTest().get());
}
TEST_F(RenderSurfaceTest, queueBufferHandlesClientComposition) {
- sp<GraphicBuffer> buffer = new GraphicBuffer();
- mSurface.mutableGraphicBufferForTest() = buffer;
+ const auto buffer = std::make_shared<renderengine::ExternalTexture>(new GraphicBuffer(),
+ mRenderEngine, false);
+ mSurface.mutableTextureForTest() = buffer;
impl::OutputCompositionState state;
state.usesClientComposition = true;
state.flipClientTarget = false;
EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
- EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
+ EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
+ EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
}
TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequest) {
- sp<GraphicBuffer> buffer = new GraphicBuffer();
- mSurface.mutableGraphicBufferForTest() = buffer;
+ const auto buffer = std::make_shared<renderengine::ExternalTexture>(new GraphicBuffer(),
+ mRenderEngine, false);
+ mSurface.mutableTextureForTest() = buffer;
impl::OutputCompositionState state;
state.usesClientComposition = false;
state.flipClientTarget = true;
EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
- EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
+ EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
+ EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
}
TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequestWithNoBufferYetDequeued) {
@@ -317,27 +324,28 @@
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
+ EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
}
TEST_F(RenderSurfaceTest, queueBufferHandlesNativeWindowQueueBufferFailureOnVirtualDisplay) {
- sp<GraphicBuffer> buffer = new GraphicBuffer();
- mSurface.mutableGraphicBufferForTest() = buffer;
+ const auto buffer = std::make_shared<renderengine::ExternalTexture>(new GraphicBuffer(),
+ mRenderEngine, false);
+ mSurface.mutableTextureForTest() = buffer;
impl::OutputCompositionState state;
state.usesClientComposition = true;
EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state));
- EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1))
+ EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
.WillOnce(Return(INVALID_OPERATION));
EXPECT_CALL(mDisplay, isVirtual()).WillOnce(Return(true));
- EXPECT_CALL(*mNativeWindow, cancelBuffer(buffer->getNativeBuffer(), -1))
+ EXPECT_CALL(*mNativeWindow, cancelBuffer(buffer->getBuffer()->getNativeBuffer(), -1))
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1);
mSurface.queueBuffer(base::unique_fd());
- EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get());
+ EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get());
}
/*
diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
index f01fe27..283c692 100644
--- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp
@@ -305,8 +305,8 @@
const auto drawLayers = [&](const renderengine::DisplaySettings& displaySettings,
const std::vector<const renderengine::LayerSettings*>& layers,
- const sp<GraphicBuffer>&, const bool, base::unique_fd&&,
- base::unique_fd*) -> size_t {
+ const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
+ base::unique_fd&&, base::unique_fd*) -> size_t {
EXPECT_EQ(Rect(0, 0, 2, 2), displaySettings.physicalDisplay);
EXPECT_EQ(mOutputState.layerStackSpace.content, displaySettings.clip);
EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.orientation),
@@ -321,7 +321,6 @@
EXPECT_CALL(*layerFE1, prepareClientCompositionList(_)).WillOnce(Return(clientCompList1));
EXPECT_CALL(*layerFE2, prepareClientCompositionList(_)).WillOnce(Return(clientCompList2));
EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Invoke(drawLayers));
- EXPECT_CALL(mRenderEngine, cacheExternalTextureBuffer(_));
cachedSet.render(mRenderEngine, mOutputState);
expectReadyBuffer(cachedSet);
@@ -331,7 +330,6 @@
cachedSet.getOutputSpace().bounds);
// Now check that appending a new cached set properly cleans up RenderEngine resources.
- EXPECT_CALL(mRenderEngine, unbindExternalTextureBuffer(_));
CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get();
cachedSet.append(CachedSet(layer3));
}