Always submit after texture uploads

Ensure GrContext::submit() is always called after either
Bitmap#prepareToDraw() or if DrawFrameTask skipped drawing.

In either case texture uploads & deletions will be scheduled,
but without the submit they won't actually be performed. This
can end up running out of RAM.

Bug: 189393671
Test: manual test app
Change-Id: I57477c64457558487e9e5ec0a979ad9099a8cb2c
(cherry picked from commit cf1170fbda6ba5dc3d6890c489d7521cdc6fc3b7)
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 44a6e43..4e7471d 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -207,12 +207,16 @@
 
 void SkiaPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
     GrDirectContext* context = thread.getGrContext();
-    if (context) {
+    if (context && !bitmap->isHardware()) {
         ATRACE_FORMAT("Bitmap#prepareToDraw %dx%d", bitmap->width(), bitmap->height());
         auto image = bitmap->makeImage();
-        if (image.get() && !bitmap->isHardware()) {
+        if (image.get()) {
             SkImage_pinAsTexture(image.get(), context);
             SkImage_unpinAsTexture(image.get(), context);
+            // A submit is necessary as there may not be a frame coming soon, so without a call
+            // to submit these texture uploads can just sit in the queue building up until
+            // we run out of RAM
+            context->flushAndSubmit();
         }
     }
 }
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 5c4b901..db29e34 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -130,6 +130,12 @@
     if (CC_LIKELY(canDrawThisFrame)) {
         dequeueBufferDuration = context->draw();
     } else {
+        // Do a flush in case syncFrameState performed any texture uploads. Since we skipped
+        // the draw() call, those uploads (or deletes) will end up sitting in the queue.
+        // Do them now
+        if (GrDirectContext* grContext = mRenderThread->getGrContext()) {
+            grContext->flushAndSubmit();
+        }
         // wait on fences so tasks don't overlap next frame
         context->waitOnFences();
     }