lock special-raster while the caller's bitmap is in-scope

previous CL that removed the specialimage subclass that wrapped the original image: https://codereview.chromium.org/2164073004

BUG=skia:5574
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2183483003

Review-Url: https://codereview.chromium.org/2183483003
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index fa7cbc6..c10e88e 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -209,12 +209,15 @@
 public:
     SkSpecialImage_Raster(const SkIRect& subset, const SkBitmap& bm, const SkSurfaceProps* props)
         : INHERITED(subset, bm.getGenerationID(), props)
-        , fBitmap(bm) {
-        if (bm.pixelRef() && bm.pixelRef()->isPreLocked()) {
-            // we only preemptively lock if there is no chance of triggering something expensive
-            // like a lazy decode or imagegenerator. PreLocked means it is flat pixels already.
-            fBitmap.lockPixels();
-        }
+        , fBitmap(bm)
+    {
+        SkASSERT(bm.pixelRef());
+
+        // We have to lock now, while bm is still in scope, since it may have come from our
+        // cache, which means we need to keep it locked until we (the special) are done, since
+        // we cannot re-generate the cache entry (if bm came from a generator).
+        fBitmap.lockPixels();
+        SkASSERT(fBitmap.getPixels());
     }
 
     bool isOpaque() const override { return fBitmap.isOpaque(); }
@@ -292,6 +295,10 @@
                                                      const SkSurfaceProps* props) {
     SkASSERT(rect_fits(subset, bm.width(), bm.height()));
 
+    if (!bm.pixelRef()) {
+        return nullptr;
+    }
+
     const SkBitmap* srcBM = &bm;
     SkBitmap tmpStorage;
     // ImageFilters only handle N32 at the moment, so force our src to be that