Fix failed filter followed by an affects-transparent-black filter.

When an upstream filter returns null, either through failure or clipping, a downstream affects-transparent-black
filter should still produce non-transparent pixels.

This patch fixes SkColorFilterImageFilter.

Note: this will affect the results of the imagefilterscropexpand GM.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1844593002

Review URL: https://codereview.chromium.org/1844593002
diff --git a/tests/ImageFilterTest.cpp b/tests/ImageFilterTest.cpp
index e6430b4..21ddc16 100644
--- a/tests/ImageFilterTest.cpp
+++ b/tests/ImageFilterTest.cpp
@@ -86,6 +86,36 @@
     typedef SkImageFilter INHERITED;
 };
 
+class FailImageFilter : public SkImageFilter {
+public:
+    FailImageFilter() : SkImageFilter(0, nullptr) {
+    }
+
+    sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source,
+                                        const Context& ctx,
+                                        SkIPoint* offset) const override {
+        return nullptr;
+    }
+
+    SK_TO_STRING_OVERRIDE()
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(FailImageFilter)
+
+private:
+    typedef SkImageFilter INHERITED;
+};
+
+sk_sp<SkFlattenable> FailImageFilter::CreateProc(SkReadBuffer& buffer) {
+    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
+    return sk_sp<SkFlattenable>(new FailImageFilter());
+}
+
+#ifndef SK_IGNORE_TO_STRING
+void FailImageFilter::toString(SkString* str) const {
+    str->appendf("FailImageFilter: (");
+    str->append(")");
+}
+#endif
+
 void draw_gradient_circle(SkCanvas* canvas, int width, int height) {
     SkScalar x = SkIntToScalar(width / 2);
     SkScalar y = SkIntToScalar(height / 2);
@@ -673,6 +703,40 @@
 }
 #endif
 
+
+// Tests that, even when an upstream filter has returned null (due to failure or clipping), a
+// downstream filter that affects transparent black still does so even with a nullptr input.
+static void test_fail_affects_transparent_black(SkImageFilter::Proxy* proxy,
+                                                skiatest::Reporter* reporter,
+                                                GrContext* context) {
+    sk_sp<FailImageFilter> failFilter(new FailImageFilter());
+    sk_sp<SkSpecialImage> source(create_empty_special_image(context, proxy, 5));
+    SkImageFilter::Context ctx(SkMatrix::I(), SkIRect::MakeXYWH(0, 0, 1, 1), nullptr);
+    sk_sp<SkColorFilter> green(SkColorFilter::MakeModeFilter(SK_ColorGREEN, SkXfermode::kSrc_Mode));
+    SkASSERT(green->affectsTransparentBlack());
+    sk_sp<SkImageFilter> greenFilter(SkColorFilterImageFilter::Create(green.get(),
+                                                                      failFilter.get()));
+    SkIPoint offset;
+    sk_sp<SkSpecialImage> result(greenFilter->filterImage(source.get(), ctx, &offset));
+    REPORTER_ASSERT(reporter, nullptr != result.get());
+    if (result.get()) {
+        SkBitmap resultBM;
+        TestingSpecialImageAccess::GetROPixels(result.get(), &resultBM);
+        SkAutoLockPixels lock(resultBM);
+        REPORTER_ASSERT(reporter, *resultBM.getAddr32(0, 0) == SK_ColorGREEN);
+    }
+}
+
+DEF_TEST(ImageFilterFailAffectsTransparentBlack, reporter) {
+    run_raster_test(reporter, 100, test_fail_affects_transparent_black);
+}
+
+#if SK_SUPPORT_GPU
+DEF_GPUTEST_FOR_NATIVE_CONTEXT(ImageFilterFailAffectsTransparentBlack_Gpu, reporter, context) {
+    run_gpu_test(reporter, context, 100, test_fail_affects_transparent_black);
+}
+#endif
+
 DEF_TEST(ImageFilterDrawTiled, reporter) {
     // Check that all filters when drawn tiled (with subsequent clip rects) exactly
     // match the same filters drawn with a single full-canvas bitmap draw.