Don't execute onFlush op lists until after GPU data is uploaded
Bug: skia:
Change-Id: Ide85e802fd6e6a19412457dbaded3545b962c240
Reviewed-on: https://skia-review.googlesource.com/55562
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index f1e116f..6076609 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -137,6 +137,8 @@
GrOnFlushResourceProvider onFlushProvider(this);
+ // Prepare any onFlush op lists (e.g. atlases).
+ SkSTArray<8, sk_sp<GrOpList>> onFlushOpLists;
if (!fOnFlushCBObjects.empty()) {
// MDB TODO: pre-MDB '1' is the correct pre-allocated size. Post-MDB it will need
// to be larger.
@@ -144,27 +146,19 @@
for (int i = 0; i < fOpLists.count(); ++i) {
opListIds[i] = fOpLists[i]->uniqueID();
}
-
- SkSTArray<1, sk_sp<GrRenderTargetContext>> renderTargetContexts;
+ SkSTArray<4, sk_sp<GrRenderTargetContext>> renderTargetContexts;
for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) {
onFlushCBObject->preFlush(&onFlushProvider,
opListIds.get(), opListIds.count(),
&renderTargetContexts);
- if (!renderTargetContexts.count()) {
- continue; // This is fine. No atlases of this type are required for this flush
- }
-
- for (int j = 0; j < renderTargetContexts.count(); ++j) {
- GrOpList* opList = renderTargetContexts[j]->getOpList();
- if (!opList) {
+ for (const sk_sp<GrRenderTargetContext>& rtc : renderTargetContexts) {
+ sk_sp<GrOpList> onFlushOpList = sk_ref_sp(rtc->getOpList());
+ if (!onFlushOpList) {
continue; // Odd - but not a big deal
}
- SkASSERT(opList->unique());
- opList->makeClosed(*fContext->caps());
- opList->prepare(&fFlushState);
- if (!opList->execute(&fFlushState)) {
- continue; // This is bad
- }
+ onFlushOpList->makeClosed(*fContext->caps());
+ onFlushOpList->prepare(&fFlushState);
+ onFlushOpLists.push_back(std::move(onFlushOpList));
}
renderTargetContexts.reset();
}
@@ -201,6 +195,17 @@
// Upload all data to the GPU
fFlushState.preIssueDraws();
+ // Execute the onFlush op lists first, if any.
+ for (sk_sp<GrOpList>& onFlushOpList : onFlushOpLists) {
+ if (!onFlushOpList->execute(&fFlushState)) {
+ SkDebugf("WARNING: onFlushOpList failed to execute.\n");
+ }
+ SkASSERT(onFlushOpList->unique());
+ onFlushOpList = nullptr;
+ }
+ onFlushOpLists.reset();
+
+ // Execute the normal op lists.
for (int i = 0; i < fOpLists.count(); ++i) {
if (!fOpLists[i]) {
continue;
@@ -227,6 +232,7 @@
// https://bugs.chromium.org/p/skia/issues/detail?id=7111
fOpLists[i]->endFlush();
}
+ fOpLists[i] = nullptr;
}
fOpLists.reset();
diff --git a/tests/OnFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp
index e47a76b..3701651 100644
--- a/tests/OnFlushCallbackTest.cpp
+++ b/tests/OnFlushCallbackTest.cpp
@@ -166,16 +166,6 @@
} // anonymous namespace
-#ifdef SK_DEBUG
-#include "SkImageEncoder.h"
-#include "sk_tool_utils.h"
-
-static void save_bm(const SkBitmap& bm, const char name[]) {
- bool result = sk_tool_utils::EncodeImageToFile(name, bm, SkEncodedImageFormat::kPNG, 100);
- SkASSERT(result);
-}
-#endif
-
static constexpr SkRect kEmptyRect = SkRect::MakeEmpty();
namespace {
@@ -294,23 +284,6 @@
fAtlasDest = atlasDest;
}
- void saveRTC(sk_sp<GrRenderTargetContext> rtc) {
- SkASSERT(!fRTC);
- fRTC = rtc;
- }
-
-#ifdef SK_DEBUG
- void saveAtlasToDisk() {
- SkBitmap readBack;
- readBack.allocN32Pixels(fRTC->width(), fRTC->height());
-
- bool result = fRTC->readPixels(readBack.info(),
- readBack.getPixels(), readBack.rowBytes(), 0, 0);
- SkASSERT(result);
- save_bm(readBack, "atlas-real.png");
- }
-#endif
-
/*
* This callback back creates the atlas and updates the AtlasedRectOps to read from it
*/
@@ -389,9 +362,6 @@
this->clearOpsFor(lists[i]);
}
- // Hide a ref to the RTC in AtlasData so we can check on it later
- this->saveRTC(rtc);
-
results->push_back(std::move(rtc));
}
@@ -420,9 +390,6 @@
// Each opList containing AtlasedRectOps gets its own internal singly-linked list
SkTDArray<LinkedListHeader> fOps;
- // The RTC used to create the atlas
- sk_sp<GrRenderTargetContext> fRTC;
-
// For the time being we need to pre-allocate the atlas bc the TextureSamplers require
// a GrTexture
sk_sp<GrTextureProxy> fAtlasDest;
@@ -467,7 +434,14 @@
// Enable this if you want to debug the final draws w/o having the atlasCallback create the
// atlas
#if 0
+#include "SkImageEncoder.h"
#include "SkGrPriv.h"
+#include "sk_tool_utils.h"
+
+static void save_bm(const SkBitmap& bm, const char name[]) {
+ bool result = sk_tool_utils::EncodeImageToFile(name, bm, SkEncodedImageFormat::kPNG, 100);
+ SkASSERT(result);
+}
sk_sp<GrTextureProxy> pre_create_atlas(GrContext* context) {
SkBitmap bm;
@@ -601,11 +575,6 @@
object.markAsDone();
-#if 0
- save_bm(readBack, "atlas-final-image.png");
- data.saveAtlasToDisk();
-#endif
-
int x = kDrawnTileSize/2;
test_color(reporter, readBack, x, SK_ColorRED);
x += kDrawnTileSize;