Cache output Framebuffer for RenderEngine::drawLayers
GL comp is now fast.
Also:
* Add additional ATRACE_CALLs
* Remove some todos that we might not get to/are obsolete
Bug: 123107664
Change-Id: I8649e074f8234ccaeb28bb2be6c11a380a808d8f
Test: systrace
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 3d6ac8f..8f9071e 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -424,6 +424,7 @@
mTraceGpuCompletion = true;
mFlushTracer = std::make_unique<FlushTracer>(this);
}
+ mDrawingBuffer = createFramebuffer();
}
GLESRenderEngine::~GLESRenderEngine() {
@@ -439,6 +440,10 @@
return std::make_unique<GLImage>(*this);
}
+Framebuffer* GLESRenderEngine::getFramebufferForDrawing() {
+ return mDrawingBuffer.get();
+}
+
void GLESRenderEngine::primeCache() const {
ProgramCache::getInstance().primeCache(mInProtectedContext ? mProtectedEGLContext : mEGLContext,
mFeatureFlags & USE_COLOR_MANAGEMENT);
@@ -678,6 +683,7 @@
}
void GLESRenderEngine::evictImages(const std::vector<LayerSettings>& layers) {
+ ATRACE_CALL();
// destroy old image references that we're not going to draw with.
std::unordered_set<uint64_t> bufIds;
for (auto layer : layers) {
@@ -744,6 +750,7 @@
}
void GLESRenderEngine::unbindFrameBuffer(Framebuffer* /* framebuffer */) {
+ ATRACE_CALL();
mFboHeight = 0;
// back to main framebuffer
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 34187f1..7b72666 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -88,6 +88,7 @@
EGLConfig getEGLConfig() const { return mEGLConfig; }
protected:
+ Framebuffer* getFramebufferForDrawing() override;
void dump(std::string& result) override;
void setViewportAndProjection(size_t vpw, size_t vph, Rect sourceCrop,
ui::Transform::orientation_flags rotation) override;
@@ -191,6 +192,8 @@
// more complicated interface.
std::unordered_map<uint64_t, std::unique_ptr<Image>> mImageCache;
+ std::unique_ptr<Framebuffer> mDrawingBuffer;
+
class FlushTracer {
public:
FlushTracer(GLESRenderEngine* engine);
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index bc1a4da..b51ed22 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -174,37 +174,37 @@
// fence.
// @return An error code indicating whether drawing was successful. For
// now, this always returns NO_ERROR.
- // TODO(alecmouri): Consider making this a multi-display API, so that the
- // caller deoes not need to handle multiple fences.
virtual status_t drawLayers(const DisplaySettings& display,
const std::vector<LayerSettings>& layers,
ANativeWindowBuffer* buffer, base::unique_fd* drawFence) = 0;
- // TODO(alecmouri): Expose something like bindTexImage() so that devices
- // that don't support native sync fences can get rid of code duplicated
- // between BufferStateLayer and BufferQueueLayer for binding an external
- // texture.
-
- // TODO(alecmouri): Add API to help with managing a texture pool.
+protected:
+ // Gets a framebuffer to render to. This framebuffer may or may not be
+ // cached depending on the implementation.
+ //
+ // Note that this method does not transfer ownership, so the caller most not
+ // live longer than RenderEngine.
+ virtual Framebuffer* getFramebufferForDrawing() = 0;
+ friend class BindNativeBufferAsFramebuffer;
};
class BindNativeBufferAsFramebuffer {
public:
BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer)
- : mEngine(engine), mFramebuffer(mEngine.createFramebuffer()), mStatus(NO_ERROR) {
+ : mEngine(engine), mFramebuffer(mEngine.getFramebufferForDrawing()), mStatus(NO_ERROR) {
mStatus = mFramebuffer->setNativeWindowBuffer(buffer, mEngine.isProtected())
- ? mEngine.bindFrameBuffer(mFramebuffer.get())
+ ? mEngine.bindFrameBuffer(mFramebuffer)
: NO_MEMORY;
}
~BindNativeBufferAsFramebuffer() {
mFramebuffer->setNativeWindowBuffer(nullptr, false);
- mEngine.unbindFrameBuffer(mFramebuffer.get());
+ mEngine.unbindFrameBuffer(mFramebuffer);
}
status_t getStatus() const { return mStatus; }
private:
RenderEngine& mEngine;
- std::unique_ptr<Framebuffer> mFramebuffer;
+ Framebuffer* mFramebuffer;
status_t mStatus;
};
diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
index 4b86cfe..800eac3 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -36,6 +36,7 @@
MOCK_METHOD0(createFramebuffer, std::unique_ptr<renderengine::Framebuffer>());
MOCK_METHOD0(createImage, std::unique_ptr<renderengine::Image>());
+ MOCK_METHOD0(getFramebufferForDrawing, Framebuffer*());
MOCK_CONST_METHOD0(primeCache, void());
MOCK_METHOD1(dump, void(std::string&));
MOCK_CONST_METHOD0(useNativeFenceSync, bool());
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 123b4e4..a4a3612 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3321,7 +3321,6 @@
void SurfaceFlinger::doDisplayComposition(const sp<DisplayDevice>& displayDevice,
const Region& inDirtyRegion) {
auto display = displayDevice->getCompositionDisplay();
-
// We only need to actually compose the display if:
// 1) It is being handled by hardware composer, which may need this to
// keep its virtual display state machine in sync, or
@@ -3341,6 +3340,7 @@
bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& displayDevice,
const Region& debugRegion, base::unique_fd* readyFence) {
+ ATRACE_CALL();
ALOGV("doComposeSurfaces");
auto display = displayDevice->getCompositionDisplay();
@@ -3467,6 +3467,7 @@
firstLayer = false;
}
+ // Perform some cleanup steps if we used client composition.
if (hasClientComposition) {
clientCompositionDisplay.clearRegion = clearRegion;
if (!debugRegion.isEmpty()) {