Conditionally cache RenderEffect results

Added property to conditionally cache SkImage instances
with SkImageFilters applied. Some GL vendor implementations
invoke Fence::waitForver without signalling, leading
to ANRs throughout the system.

Bug: 193145089
Test: manual
Change-Id: I3e478b11b66205d96e9499a362f7412a1d6e952d
Merged-In: I3e478b11b66205d96e9499a362f7412a1d6e952d
This commit is contained in:
Nader Jawad
2021-09-20 21:22:50 -07:00
parent 5837f7b41b
commit 10f05d8f00
4 changed files with 33 additions and 8 deletions

View File

@@ -50,6 +50,7 @@ bool Properties::showDirtyRegions = false;
bool Properties::skipEmptyFrames = true;
bool Properties::useBufferAge = true;
bool Properties::enablePartialUpdates = true;
bool Properties::enableRenderEffectCache = false;
DebugLevel Properties::debugLevel = kDebugDisabled;
OverdrawColorSet Properties::overdrawColorSet = OverdrawColorSet::Default;

View File

@@ -224,6 +224,7 @@ public:
static bool skipEmptyFrames;
static bool useBufferAge;
static bool enablePartialUpdates;
static bool enableRenderEffectCache;
// TODO: Move somewhere else?
static constexpr float textGamma = 1.45f;

View File

@@ -231,14 +231,34 @@ void RenderNodeDrawable::drawContent(SkCanvas* canvas) const {
SkASSERT(properties.effectiveLayerType() == LayerType::RenderLayer);
SkPaint paint;
layerNeedsPaint(layerProperties, alphaMultiplier, &paint);
const auto snapshotResult = renderNode->updateSnapshotIfRequired(
canvas->recordingContext(),
layerProperties.getImageFilter(),
clipBounds.roundOut()
);
sk_sp<SkImage> snapshotImage = snapshotResult->snapshot;
srcBounds = snapshotResult->outSubset;
offset = snapshotResult->outOffset;
sk_sp<SkImage> snapshotImage;
auto* imageFilter = layerProperties.getImageFilter();
auto recordingContext = canvas->recordingContext();
// On some GL vendor implementations, caching the result of
// getLayerSurface->makeImageSnapshot() causes a call to
// Fence::waitForever without a corresponding signal. This would
// lead to ANRs throughout the system.
// Instead only cache the SkImage created with the SkImageFilter
// for supported devices. Otherwise just create a new SkImage with
// the corresponding SkImageFilter each time.
// See b/193145089 and b/197263715
if (!Properties::enableRenderEffectCache) {
if (imageFilter) {
auto subset = SkIRect::MakeWH(srcBounds.width(), srcBounds.height());
snapshotImage = snapshotImage->makeWithFilter(recordingContext, imageFilter,
subset, clipBounds.roundOut(),
&srcBounds, &offset);
} else {
snapshotImage = renderNode->getLayerSurface()->makeImageSnapshot();
}
} else {
const auto snapshotResult = renderNode->updateSnapshotIfRequired(
recordingContext, layerProperties.getImageFilter(), clipBounds.roundOut());
snapshotImage = snapshotResult->snapshot;
srcBounds = snapshotResult->outSubset;
offset = snapshotResult->outOffset;
}
const auto dstBounds = SkIRect::MakeXYWH(offset.x(),
offset.y(),
srcBounds.width(),

View File

@@ -146,6 +146,9 @@ void EglManager::initialize() {
LOG_ALWAYS_FATAL("Unsupported wide color space.");
}
mHasWideColorGamutSupport = EglExtensions.glColorSpace && hasWideColorSpaceExtension;
auto* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
Properties::enableRenderEffectCache = (strcmp(vendor, "Qualcomm") != 0);
}
EGLConfig EglManager::load8BitsConfig(EGLDisplay display, EglManager::SwapBehavior swapBehavior) {