First patch for async renderengine.
1. return a std::future object from DrawLayers() instead to make it
asynchronously
2. retire drawFence value from drawLayers() parameter list.
Bug: 180657548
Test: android.hardware.graphics.composer@2.2-vts, libcompositionengine_test, libsurfaceflinger_unittest and
librenderengine_test pass
Change-Id: If63c11762d1cce7b053cc72aaeaed6dd7904877f
diff --git a/libs/renderengine/RenderEngine.cpp b/libs/renderengine/RenderEngine.cpp
index 0c5a851..2174df5 100644
--- a/libs/renderengine/RenderEngine.cpp
+++ b/libs/renderengine/RenderEngine.cpp
@@ -95,5 +95,16 @@
"output buffer not gpu writeable");
}
+std::future<RenderEngineResult> RenderEngine::drawLayers(
+ const DisplaySettings& display, const std::vector<const LayerSettings*>& layers,
+ const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache,
+ base::unique_fd&& bufferFence) {
+ const auto resultPromise = std::make_shared<std::promise<RenderEngineResult>>();
+ std::future<RenderEngineResult> resultFuture = resultPromise->get_future();
+ drawLayersInternal(std::move(resultPromise), display, layers, buffer, useFramebufferCache,
+ std::move(bufferFence));
+ return resultFuture;
+}
+
} // namespace renderengine
} // namespace android
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index b1e1014..2375cb7 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -1078,15 +1078,16 @@
return image;
}
-status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
- const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) {
+void GLESRenderEngine::drawLayersInternal(
+ const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
+ const DisplaySettings& display, const std::vector<const LayerSettings*>& layers,
+ const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache,
+ base::unique_fd&& bufferFence) {
ATRACE_CALL();
if (layers.empty()) {
ALOGV("Drawing empty layer stack");
- return NO_ERROR;
+ resultPromise->set_value({NO_ERROR, base::unique_fd()});
+ return;
}
if (bufferFence.get() >= 0) {
@@ -1100,7 +1101,8 @@
if (buffer == nullptr) {
ALOGE("No output buffer provided. Aborting GPU composition.");
- return BAD_VALUE;
+ resultPromise->set_value({BAD_VALUE, base::unique_fd()});
+ return;
}
validateOutputBufferUsage(buffer->getBuffer());
@@ -1128,7 +1130,8 @@
ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).",
buffer->getBuffer()->handle);
checkErrors();
- return fbo->getStatus();
+ resultPromise->set_value({fbo->getStatus(), base::unique_fd()});
+ return;
}
setViewportAndProjection(display.physicalDisplay, display.clip);
} else {
@@ -1139,7 +1142,8 @@
ALOGE("Failed to prepare blur filter! Aborting GPU composition for buffer (%p).",
buffer->getBuffer()->handle);
checkErrors();
- return status;
+ resultPromise->set_value({status, base::unique_fd()});
+ return;
}
}
@@ -1172,7 +1176,8 @@
ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).",
buffer->getBuffer()->handle);
checkErrors("Can't render first blur pass");
- return status;
+ resultPromise->set_value({status, base::unique_fd()});
+ return;
}
if (blurLayers.size() == 0) {
@@ -1194,7 +1199,8 @@
ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).",
buffer->getBuffer()->handle);
checkErrors("Can't bind native framebuffer");
- return status;
+ resultPromise->set_value({status, base::unique_fd()});
+ return;
}
status = mBlurFilter->render(blurLayersSize > 1);
@@ -1202,7 +1208,8 @@
ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).",
buffer->getBuffer()->handle);
checkErrors("Can't render blur filter");
- return status;
+ resultPromise->set_value({status, base::unique_fd()});
+ return;
}
}
@@ -1289,30 +1296,31 @@
}
}
- if (drawFence != nullptr) {
- *drawFence = flush();
- }
+ base::unique_fd drawFence = flush();
+
// If flush failed or we don't support native fences, we need to force the
// gl command stream to be executed.
- if (drawFence == nullptr || drawFence->get() < 0) {
+ if (drawFence.get() < 0) {
bool success = finish();
if (!success) {
ALOGE("Failed to flush RenderEngine commands");
checkErrors();
// Chances are, something illegal happened (either the caller passed
// us bad parameters, or we messed up our shader generation).
- return INVALID_OPERATION;
+ resultPromise->set_value({INVALID_OPERATION, std::move(drawFence)});
+ return;
}
mLastDrawFence = nullptr;
} else {
// The caller takes ownership of drawFence, so we need to duplicate the
// fd here.
- mLastDrawFence = new Fence(dup(drawFence->get()));
+ mLastDrawFence = new Fence(dup(drawFence.get()));
}
mPriorResourcesCleaned = false;
checkErrors();
- return NO_ERROR;
+ resultPromise->set_value({NO_ERROR, std::move(drawFence)});
+ return;
}
void GLESRenderEngine::setViewportAndProjection(Rect viewport, Rect clip) {
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 14627ce..c4adfdf 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -63,11 +63,6 @@
bool isProtected() const override { return mInProtectedContext; }
bool supportsProtectedContent() const override;
void useProtectedContext(bool useProtectedContext) override;
- status_t drawLayers(const DisplaySettings& display,
- const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) override;
void cleanupPostRender() override;
int getContextPriority() override;
bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
@@ -107,6 +102,11 @@
EXCLUDES(mRenderingMutex);
void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex);
bool canSkipPostRenderCleanup() const override;
+ void drawLayersInternal(const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
+ const DisplaySettings& display,
+ const std::vector<const LayerSettings*>& layers,
+ const std::shared_ptr<ExternalTexture>& buffer,
+ const bool useFramebufferCache, base::unique_fd&& bufferFence) override;
private:
friend class BindNativeBufferAsFramebuffer;
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 967cf5d..701c1f2 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -68,6 +68,7 @@
class Mesh;
class Texture;
struct RenderEngineCreationArgs;
+struct RenderEngineResult;
namespace threaded {
class RenderEngineThreaded;
@@ -156,17 +157,12 @@
// parameter does nothing.
// @param bufferFence Fence signalling that the buffer is ready to be drawn
// to.
- // @param drawFence A pointer to a fence, which will fire when the buffer
- // has been drawn to and is ready to be examined. The fence will be
- // initialized by this method. The caller will be responsible for owning the
- // fence.
- // @return An error code indicating whether drawing was successful. For
- // now, this always returns NO_ERROR.
- virtual status_t drawLayers(const DisplaySettings& display,
- const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) = 0;
+ // @return A future object of RenderEngineResult struct indicating whether
+ // drawing was successful in async mode.
+ virtual std::future<RenderEngineResult> drawLayers(
+ const DisplaySettings& display, const std::vector<const LayerSettings*>& layers,
+ const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache,
+ base::unique_fd&& bufferFence);
// Clean-up method that should be called on the main thread after the
// drawFence returned by drawLayers fires. This method will free up
@@ -232,6 +228,12 @@
friend class threaded::RenderEngineThreaded;
friend class RenderEngineTest_cleanupPostRender_cleansUpOnce_Test;
const RenderEngineType mRenderEngineType;
+
+ virtual void drawLayersInternal(
+ const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
+ const DisplaySettings& display, const std::vector<const LayerSettings*>& layers,
+ const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache,
+ base::unique_fd&& bufferFence) = 0;
};
struct RenderEngineCreationArgs {
@@ -318,6 +320,13 @@
RenderEngine::RenderEngineType::SKIA_GL_THREADED;
};
+struct RenderEngineResult {
+ // status indicates if drawing is successful
+ status_t status;
+ // drawFence will fire when the buffer has been drawn to and is ready to be examined.
+ base::unique_fd drawFence;
+};
+
} // namespace renderengine
} // namespace android
diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
index 0be3ba6..a7e6809 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -47,10 +47,15 @@
MOCK_METHOD1(useProtectedContext, void(bool));
MOCK_METHOD0(cleanupPostRender, void());
MOCK_CONST_METHOD0(canSkipPostRenderCleanup, bool());
- MOCK_METHOD6(drawLayers,
- status_t(const DisplaySettings&, const std::vector<const LayerSettings*>&,
- const std::shared_ptr<ExternalTexture>&, const bool, base::unique_fd&&,
- base::unique_fd*));
+ MOCK_METHOD5(drawLayers,
+ std::future<RenderEngineResult>(const DisplaySettings&,
+ const std::vector<const LayerSettings*>&,
+ const std::shared_ptr<ExternalTexture>&,
+ const bool, base::unique_fd&&));
+ MOCK_METHOD6(drawLayersInternal,
+ void(const std::shared_ptr<std::promise<RenderEngineResult>>&&,
+ const DisplaySettings&, const std::vector<const LayerSettings*>&,
+ const std::shared_ptr<ExternalTexture>&, const bool, base::unique_fd&&));
MOCK_METHOD0(cleanFramebufferCache, void());
MOCK_METHOD0(getContextPriority, int());
MOCK_METHOD0(supportsBackgroundBlur, bool());
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index 01df6a6..e796f66 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -95,7 +95,6 @@
.alpha = 1,
};
- base::unique_fd drawFence;
auto layers = std::vector<const LayerSettings*>{&layer, &caster};
// Four combinations of settings are used (two transforms here, and drawShadowLayers is
// called with two different destination data spaces) They're all rounded rect.
@@ -116,7 +115,7 @@
layer.geometry.positionTransform = transform;
caster.geometry.positionTransform = transform;
renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
- base::unique_fd(), &drawFence);
+ base::unique_fd());
}
}
@@ -141,7 +140,6 @@
}},
};
- base::unique_fd drawFence;
auto layers = std::vector<const LayerSettings*>{&layer};
for (auto dataspace : {kDestDataSpace, kOtherDataSpace}) {
layer.sourceDataspace = dataspace;
@@ -155,7 +153,7 @@
for (auto alpha : {half(.2f), half(1.0f)}) {
layer.alpha = alpha;
renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
- base::unique_fd(), &drawFence);
+ base::unique_fd());
}
}
}
@@ -178,14 +176,13 @@
.alpha = 0.5,
};
- base::unique_fd drawFence;
auto layers = std::vector<const LayerSettings*>{&layer};
for (auto transform : {mat4(), kScaleAndTranslate}) {
layer.geometry.positionTransform = transform;
for (float roundedCornersRadius : {0.0f, 50.f}) {
layer.geometry.roundedCornersRadius = roundedCornersRadius;
renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
- base::unique_fd(), &drawFence);
+ base::unique_fd());
}
}
}
@@ -204,13 +201,12 @@
.skipContentDraw = true,
};
- base::unique_fd drawFence;
auto layers = std::vector<const LayerSettings*>{&layer};
// Different blur code is invoked for radii less and greater than 30 pixels
for (int radius : {9, 60}) {
layer.backgroundBlurRadius = radius;
renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
- base::unique_fd(), &drawFence);
+ base::unique_fd());
}
}
@@ -246,7 +242,6 @@
},
};
- base::unique_fd drawFence;
auto layers = std::vector<const LayerSettings*>{&layer};
for (auto pixelSource : {bufferSource, bufferOpaque, colorSource}) {
layer.source = pixelSource;
@@ -258,7 +253,7 @@
for (float alpha : {0.5f, 1.f}) {
layer.alpha = alpha,
renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
- base::unique_fd(), &drawFence);
+ base::unique_fd());
}
}
}
@@ -294,10 +289,8 @@
};
- base::unique_fd drawFence;
auto layers = std::vector<const LayerSettings*>{&layer};
- renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
- base::unique_fd(), &drawFence);
+ renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd());
}
static void drawHolePunchLayer(SkiaRenderEngine* renderengine, const DisplaySettings& display,
@@ -324,10 +317,8 @@
};
- base::unique_fd drawFence;
auto layers = std::vector<const LayerSettings*>{&layer};
- renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
- base::unique_fd(), &drawFence);
+ renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd());
}
//
@@ -436,8 +427,10 @@
.source = PixelSource{.solidColor = half3(0.f, 0.f, 0.f)},
};
auto layers = std::vector<const LayerSettings*>{&layer};
- renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache,
- base::unique_fd(), nullptr); // null drawFence makes it synchronous
+ // call get() to make it synchronous
+ renderengine
+ ->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd())
+ .get();
const nsecs_t timeAfter = systemTime();
const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 9fbbdc3..052c61f 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -713,17 +713,18 @@
return roundedRect;
}
-status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
- const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool /*useFramebufferCache*/,
- base::unique_fd&& bufferFence, base::unique_fd* drawFence) {
+void SkiaGLRenderEngine::drawLayersInternal(
+ const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
+ const DisplaySettings& display, const std::vector<const LayerSettings*>& layers,
+ const std::shared_ptr<ExternalTexture>& buffer, const bool /*useFramebufferCache*/,
+ base::unique_fd&& bufferFence) {
ATRACE_NAME("SkiaGL::drawLayers");
std::lock_guard<std::mutex> lock(mRenderingMutex);
if (layers.empty()) {
ALOGV("Drawing empty layer stack");
- return NO_ERROR;
+ resultPromise->set_value({NO_ERROR, base::unique_fd()});
+ return;
}
if (bufferFence.get() >= 0) {
@@ -736,7 +737,8 @@
}
if (buffer == nullptr) {
ALOGE("No output buffer provided. Aborting GPU composition.");
- return BAD_VALUE;
+ resultPromise->set_value({BAD_VALUE, base::unique_fd()});
+ return;
}
validateOutputBufferUsage(buffer->getBuffer());
@@ -765,7 +767,8 @@
SkCanvas* dstCanvas = mCapture->tryCapture(dstSurface.get());
if (dstCanvas == nullptr) {
ALOGE("Cannot acquire canvas from Skia.");
- return BAD_VALUE;
+ resultPromise->set_value({BAD_VALUE, base::unique_fd()});
+ return;
}
// setup color filter if necessary
@@ -1094,13 +1097,11 @@
activeSurface->flush();
}
- if (drawFence != nullptr) {
- *drawFence = flush();
- }
+ base::unique_fd drawFence = flush();
// If flush failed or we don't support native fences, we need to force the
// gl command stream to be executed.
- bool requireSync = drawFence == nullptr || drawFence->get() < 0;
+ bool requireSync = drawFence.get() < 0;
if (requireSync) {
ATRACE_BEGIN("Submit(sync=true)");
} else {
@@ -1112,11 +1113,13 @@
ALOGE("Failed to flush RenderEngine commands");
// Chances are, something illegal happened (either the caller passed
// us bad parameters, or we messed up our shader generation).
- return INVALID_OPERATION;
+ resultPromise->set_value({INVALID_OPERATION, std::move(drawFence)});
+ return;
}
// checkErrors();
- return NO_ERROR;
+ resultPromise->set_value({NO_ERROR, std::move(drawFence)});
+ return;
}
inline SkRect SkiaGLRenderEngine::getSkRect(const FloatRect& rect) {
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index cc91948..0b46705 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -54,11 +54,6 @@
~SkiaGLRenderEngine() override EXCLUDES(mRenderingMutex);
std::future<void> primeCache() override;
- status_t drawLayers(const DisplaySettings& display,
- const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) override;
void cleanupPostRender() override;
void cleanFramebufferCache() override{};
int getContextPriority() override;
@@ -77,6 +72,11 @@
void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) override;
void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override;
bool canSkipPostRenderCleanup() const override;
+ void drawLayersInternal(const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
+ const DisplaySettings& display,
+ const std::vector<const LayerSettings*>& layers,
+ const std::shared_ptr<ExternalTexture>& buffer,
+ const bool useFramebufferCache, base::unique_fd&& bufferFence) override;
private:
static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h
index 7cd9eca..f61653b 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.h
+++ b/libs/renderengine/skia/SkiaRenderEngine.h
@@ -44,14 +44,6 @@
virtual void deleteTextures(size_t /*count*/, uint32_t const* /*names*/) override{};
virtual bool isProtected() const override { return false; } // mInProtectedContext; }
virtual bool supportsProtectedContent() const override { return false; };
- virtual status_t drawLayers(const DisplaySettings& /*display*/,
- const std::vector<const LayerSettings*>& /*layers*/,
- const std::shared_ptr<ExternalTexture>& /*buffer*/,
- const bool /*useFramebufferCache*/,
- base::unique_fd&& /*bufferFence*/,
- base::unique_fd* /*drawFence*/) override {
- return 0;
- };
virtual int getContextPriority() override { return 0; }
virtual void assertShadersCompiled(int numShaders) {}
virtual int reportShadersCompiled() { return 0; }
@@ -60,6 +52,14 @@
virtual void mapExternalTextureBuffer(const sp<GraphicBuffer>& /*buffer*/,
bool /*isRenderable*/) override = 0;
virtual void unmapExternalTextureBuffer(const sp<GraphicBuffer>& /*buffer*/) override = 0;
+
+ virtual void drawLayersInternal(
+ const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
+ const DisplaySettings& display, const std::vector<const LayerSettings*>& layers,
+ const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache,
+ base::unique_fd&& bufferFence) override {
+ resultPromise->set_value({NO_ERROR, base::unique_fd()});
+ };
};
} // namespace skia
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 33053a0..b3b726d 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -419,9 +419,10 @@
void invokeDraw(renderengine::DisplaySettings settings,
std::vector<const renderengine::LayerSettings*> layers) {
- base::unique_fd fence;
- status_t status =
- mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(), &fence);
+ std::future<renderengine::RenderEngineResult> result =
+ mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
+ ASSERT_TRUE(result.valid());
+ auto [status, fence] = result.get();
int fd = fence.release();
if (fd >= 0) {
@@ -1312,9 +1313,11 @@
layer.geometry.boundaries = fullscreenRect().toFloatRect();
BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
layers.push_back(&layer);
- base::unique_fd fence;
- status_t status = mRE->drawLayers(settings, layers, nullptr, true, base::unique_fd(), &fence);
+ std::future<renderengine::RenderEngineResult> result =
+ mRE->drawLayers(settings, layers, nullptr, true, base::unique_fd());
+ ASSERT_TRUE(result.valid());
+ auto [status, _] = result.get();
ASSERT_EQ(BAD_VALUE, status);
}
@@ -1333,7 +1336,10 @@
layer.alpha = 1.0;
layers.push_back(&layer);
- status_t status = mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(), nullptr);
+ std::future<renderengine::RenderEngineResult> result =
+ mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
+ ASSERT_TRUE(result.valid());
+ auto [status, _] = result.get();
ASSERT_EQ(NO_ERROR, status);
expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
}
@@ -1360,7 +1366,10 @@
layer.alpha = 1.0;
layers.push_back(&layer);
- status_t status = mRE->drawLayers(settings, layers, mBuffer, false, base::unique_fd(), nullptr);
+ std::future<renderengine::RenderEngineResult> result =
+ mRE->drawLayers(settings, layers, mBuffer, false, base::unique_fd());
+ ASSERT_TRUE(result.valid());
+ auto [status, _] = result.get();
ASSERT_EQ(NO_ERROR, status);
ASSERT_FALSE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId()));
expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
@@ -1760,10 +1769,17 @@
layer.alpha = 1.0;
layers.push_back(&layer);
- base::unique_fd fenceOne;
- mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(), &fenceOne);
- base::unique_fd fenceTwo;
- mRE->drawLayers(settings, layers, mBuffer, true, std::move(fenceOne), &fenceTwo);
+ std::future<renderengine::RenderEngineResult> resultOne =
+ mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
+ ASSERT_TRUE(resultOne.valid());
+ auto [statusOne, fenceOne] = resultOne.get();
+ ASSERT_EQ(NO_ERROR, statusOne);
+
+ std::future<renderengine::RenderEngineResult> resultTwo =
+ mRE->drawLayers(settings, layers, mBuffer, true, std::move(fenceOne));
+ ASSERT_TRUE(resultTwo.valid());
+ auto [statusTwo, fenceTwo] = resultTwo.get();
+ ASSERT_EQ(NO_ERROR, statusTwo);
const int fd = fenceTwo.get();
if (fd >= 0) {
diff --git a/libs/renderengine/tests/RenderEngineThreadedTest.cpp b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
index 830f463..99250c1 100644
--- a/libs/renderengine/tests/RenderEngineThreadedTest.cpp
+++ b/libs/renderengine/tests/RenderEngineThreadedTest.cpp
@@ -169,6 +169,7 @@
status_t result = mThreadedRE->supportsBackgroundBlur();
ASSERT_EQ(true, result);
}
+
TEST_F(RenderEngineThreadedTest, drawLayers) {
renderengine::DisplaySettings settings;
std::vector<const renderengine::LayerSettings*> layers;
@@ -177,17 +178,22 @@
renderengine::ExternalTexture::Usage::READABLE |
renderengine::ExternalTexture::Usage::WRITEABLE);
base::unique_fd bufferFence;
- base::unique_fd drawFence;
- EXPECT_CALL(*mRenderEngine, drawLayers)
- .WillOnce([](const renderengine::DisplaySettings&,
- const std::vector<const renderengine::LayerSettings*>&,
- const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
- base::unique_fd&&, base::unique_fd*) -> status_t { return NO_ERROR; });
+ EXPECT_CALL(*mRenderEngine, drawLayersInternal)
+ .WillOnce([&](const std::shared_ptr<std::promise<renderengine::RenderEngineResult>>&&
+ resultPromise,
+ const renderengine::DisplaySettings&,
+ const std::vector<const renderengine::LayerSettings*>&,
+ const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
+ base::unique_fd &&) -> void {
+ resultPromise->set_value({NO_ERROR, base::unique_fd()});
+ });
- status_t result = mThreadedRE->drawLayers(settings, layers, buffer, false,
- std::move(bufferFence), &drawFence);
- ASSERT_EQ(NO_ERROR, result);
+ std::future<renderengine::RenderEngineResult> result =
+ mThreadedRE->drawLayers(settings, layers, buffer, false, std::move(bufferFence));
+ ASSERT_TRUE(result.valid());
+ auto [status, _] = result.get();
+ ASSERT_EQ(NO_ERROR, status);
}
} // namespace android
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp
index 8e666d5..9a8201f 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -304,27 +304,33 @@
return mRenderEngine->canSkipPostRenderCleanup();
}
-status_t RenderEngineThreaded::drawLayers(const DisplaySettings& display,
- const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache,
- base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) {
+void RenderEngineThreaded::drawLayersInternal(
+ const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
+ const DisplaySettings& display, const std::vector<const LayerSettings*>& layers,
+ const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache,
+ base::unique_fd&& bufferFence) {
+ resultPromise->set_value({NO_ERROR, base::unique_fd()});
+ return;
+}
+
+std::future<RenderEngineResult> RenderEngineThreaded::drawLayers(
+ const DisplaySettings& display, const std::vector<const LayerSettings*>& layers,
+ const std::shared_ptr<ExternalTexture>& buffer, const bool useFramebufferCache,
+ base::unique_fd&& bufferFence) {
ATRACE_CALL();
- std::promise<status_t> resultPromise;
- std::future<status_t> resultFuture = resultPromise.get_future();
+ const auto resultPromise = std::make_shared<std::promise<RenderEngineResult>>();
+ std::future<RenderEngineResult> resultFuture = resultPromise->get_future();
{
std::lock_guard lock(mThreadMutex);
- mFunctionCalls.push([&resultPromise, &display, &layers, &buffer, useFramebufferCache,
- &bufferFence, &drawFence](renderengine::RenderEngine& instance) {
+ mFunctionCalls.push([resultPromise, &display, &layers, &buffer, useFramebufferCache,
+ &bufferFence](renderengine::RenderEngine& instance) {
ATRACE_NAME("REThreaded::drawLayers");
- status_t status = instance.drawLayers(display, layers, buffer, useFramebufferCache,
- std::move(bufferFence), drawFence);
- resultPromise.set_value(status);
+ instance.drawLayersInternal(std::move(resultPromise), display, layers, buffer,
+ useFramebufferCache, std::move(bufferFence));
});
}
mCondition.notify_one();
- return resultFuture.get();
+ return resultFuture;
}
void RenderEngineThreaded::cleanFramebufferCache() {
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.h b/libs/renderengine/threaded/RenderEngineThreaded.h
index b197df7..2303caa 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.h
+++ b/libs/renderengine/threaded/RenderEngineThreaded.h
@@ -56,11 +56,11 @@
void useProtectedContext(bool useProtectedContext) override;
void cleanupPostRender() override;
- status_t drawLayers(const DisplaySettings& display,
- const std::vector<const LayerSettings*>& layers,
- const std::shared_ptr<ExternalTexture>& buffer,
- const bool useFramebufferCache, base::unique_fd&& bufferFence,
- base::unique_fd* drawFence) override;
+ std::future<RenderEngineResult> drawLayers(const DisplaySettings& display,
+ const std::vector<const LayerSettings*>& layers,
+ const std::shared_ptr<ExternalTexture>& buffer,
+ const bool useFramebufferCache,
+ base::unique_fd&& bufferFence) override;
void cleanFramebufferCache() override;
int getContextPriority() override;
@@ -71,6 +71,11 @@
void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) override;
void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override;
bool canSkipPostRenderCleanup() const override;
+ void drawLayersInternal(const std::shared_ptr<std::promise<RenderEngineResult>>&& resultPromise,
+ const DisplaySettings& display,
+ const std::vector<const LayerSettings*>& layers,
+ const std::shared_ptr<ExternalTexture>& buffer,
+ const bool useFramebufferCache, base::unique_fd&& bufferFence) override;
private:
void threadMain(CreateInstanceFactory factory);