Avoid multiple font cache texture uploads
Bug #8378964
This change defers drawing into layers until after the renderer for FBO0
is ready to draw. At that point, all the precaching is done which means
all glyphs can be uploaded at once in the font caches.
Change-Id: Ie1f7a7ff30f76f06fb3dbc72c7d05e66207d1ecb
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 1899002..2998535 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -18,6 +18,8 @@
#include <utils/Log.h>
+#include "DisplayList.h"
+#include "DeferredDisplayList.h"
#include "Layer.h"
#include "LayerRenderer.h"
#include "OpenGLRenderer.h"
@@ -43,15 +45,18 @@
fbo = 0;
stencil = NULL;
debugDrawUpdate = false;
+ deferredList = NULL;
Caches::getInstance().resourceCache.incrementRefcount(this);
}
Layer::~Layer() {
- if (mesh) delete mesh;
- if (meshIndices) delete meshIndices;
if (colorFilter) Caches::getInstance().resourceCache.decrementRefcount(colorFilter);
removeFbo();
deleteTexture();
+
+ delete[] mesh;
+ delete[] meshIndices;
+ delete deferredList;
}
uint32_t Layer::computeIdealWidth(uint32_t layerWidth) {
@@ -133,5 +138,43 @@
}
}
+void Layer::defer() {
+ if (!deferredList) {
+ deferredList = new DeferredDisplayList;
+ }
+ DeferStateStruct deferredState(*deferredList, *renderer,
+ DisplayList::kReplayFlag_ClipChildren);
+
+ const float width = layer.getWidth();
+ const float height = layer.getHeight();
+
+ if (dirtyRect.isEmpty() || (dirtyRect.left <= 0 && dirtyRect.top <= 0 &&
+ dirtyRect.right >= width && dirtyRect.bottom >= height)) {
+ dirtyRect.set(0, 0, width, height);
+ }
+
+ renderer->initViewport(width, height);
+ renderer->setupFrameState(dirtyRect.left, dirtyRect.top,
+ dirtyRect.right, dirtyRect.bottom, !isBlend());
+
+ displayList->defer(deferredState, 0);
+}
+
+void Layer::flush() {
+ if (deferredList && !deferredList->isEmpty()) {
+ renderer->setViewport(layer.getWidth(), layer.getHeight());
+ renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
+ !isBlend());
+
+ deferredList->flush(*renderer, dirtyRect);
+
+ renderer->finish();
+ renderer = NULL;
+
+ dirtyRect.setEmpty();
+ deferredList->clear();
+ }
+}
+
}; // namespace uirenderer
}; // namespace android