External image generator API: return an SkPixmap instead of SkImage
authorFlorin Malita <fmalita@chromium.org>
Wed, 23 Nov 2016 15:49:20 +0000 (10:49 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 25 Nov 2016 00:12:32 +0000 (00:12 +0000)
R=reed@google.com
BUG=skia:5806

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5134

Change-Id: Ib0215f63b67f4d5b619ebe1f1b70c7d95e604871
Reviewed-on: https://skia-review.googlesource.com/5134
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>

gm/imagegeneratorexternal.cpp
include/core/SkImageGenerator.h
src/core/SkBitmapProvider.cpp
src/core/SkDevice.cpp

index 7427dd4..b6e86c4 100644 (file)
 
 namespace {
 
+void release_proc(void*, void* releaseCtx) {
+    reinterpret_cast<SkImage*>(releaseCtx)->unref();
+}
+
 class ExternalGenerator : public SkImageGenerator {
 public:
     ExternalGenerator(const SkISize size)
@@ -53,10 +57,11 @@ protected:
         const SkScalar scale = SkTMin(scaleSize.width(), scaleSize.height());
         const int lvl = SkScalarFloorToInt(-SkScalarLog2(scale));
 
-        rec->fImage = fMips[SkTPin(lvl, 0, fMips.count())];
+        const sk_sp<SkImage>& img = fMips[SkTPin(lvl, 0, fMips.count())];
+        SkAssertResult(img->peekPixels(&rec->fPixmap));
 
         const SkRect origBounds = SkRect::Make(this->getInfo().bounds());
-        const SkRect  newBounds = SkRect::Make(rec->fImage->bounds());
+        const SkRect  newBounds = SkRect::Make(img->bounds());
 
         SkMatrix srcMap = SkMatrix::MakeScale(newBounds.width()  / origBounds.width(),
                                               newBounds.height() / origBounds.height());
@@ -65,6 +70,9 @@ protected:
 
         rec->fQuality = kLow_SkFilterQuality;
 
+        rec->fReleaseProc = release_proc;
+        rec->fReleaseCtx  = SkRef(img.get());
+
         return true;
     }
 
index 6d97f40..c19cbb4 100644 (file)
@@ -196,16 +196,20 @@ public:
      *  External generator API: provides efficient access to externally-managed image data.
      *
      *  Skia calls accessScaledPixels() during rasterization, to gain temporary access to
-     *  the external pixel data, packaged as a raster SkImage.
+     *  the external pixel data.  When done, the provided callback is invoked to release the
+     *  associated resources.
      *
      *  @param srcRect     the source rect in use for the current draw
      *  @param totalMatrix full matrix in effect (mapping srcRect -> device space)
      *  @param quality     the SkFilterQuality requested for rasterization.
      *  @param rec         out param, expected to be set when the call succeeds:
      *
-     *                       - fImage wraps the external pixel data
-     *                       - fSrcRect is an adjusted srcRect
-     *                       - fQuality is the adjusted filter quality
+     *                       - fPixmap      external pixel data
+     *                       - fSrcRect     is an adjusted srcRect
+     *                       - fQuality     is the adjusted filter quality
+     *                       - fReleaseProc pixmap release callback, same signature as the
+     *                                      SkBitmap::installPixels() callback
+     *                       - fReleaseCtx  opaque release context argument
      *
      *  @return            true on success, false otherwise (error or if this API is not supported;
      *                     in this case Skia will fall back to its internal scaling and caching
@@ -218,9 +222,14 @@ public:
      */
 
     struct ScaledImageRec {
-        sk_sp<SkImage>  fImage;
+        SkPixmap        fPixmap;
         SkRect          fSrcRect;
         SkFilterQuality fQuality;
+
+        using ReleaseProcT = void (*)(void* pixels, void* releaseCtx);
+
+        ReleaseProcT    fReleaseProc;
+        void*           fReleaseCtx;
     };
 
     bool accessScaledImage(const SkRect& srcRect, const SkMatrix& totalMatrix,
index 3ec4748..20479da 100644 (file)
@@ -71,7 +71,9 @@ bool SkBitmapProvider::accessScaledImage(const SkRect& srcRect,
 
     SkImageGenerator::ScaledImageRec rec;
     if (!cacherator->directAccessScaledImage(srcRect, m, fq, &rec) ||
-        !rec.fImage->asLegacyBitmap(scaledBitmap, SkImage::kRO_LegacyBitmapMode)) {
+        !scaledBitmap->installPixels(rec.fPixmap.info(), const_cast<void*>(rec.fPixmap.addr()),
+                                     rec.fPixmap.rowBytes(), rec.fPixmap.ctable(),
+                                     rec.fReleaseProc, rec.fReleaseCtx)) {
         return false;
     }
 
index 73f412d..741273b 100644 (file)
@@ -209,11 +209,10 @@ bool SkBaseDevice::drawExternallyScaledImage(const SkDraw& draw,
         return false;
     }
 
-    SkDestinationSurfaceColorMode colorMode = this->imageInfo().colorSpace()
-        ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
-        : SkDestinationSurfaceColorMode::kLegacy;
     SkBitmap bm;
-    if (!as_IB(rec.fImage)->getROPixels(&bm, colorMode)) {
+    if (!bm.installPixels(rec.fPixmap.info(), const_cast<void*>(rec.fPixmap.addr()),
+                          rec.fPixmap.rowBytes(), rec.fPixmap.ctable(),
+                          rec.fReleaseProc, rec.fReleaseCtx)) {
         return false;
     }