Properly handle extracted bitmaps in cross process/shared addr space SkGPipe.
authorscroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 2 Jul 2012 13:35:09 +0000 (13:35 +0000)
committerscroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 2 Jul 2012 13:35:09 +0000 (13:35 +0000)
Use the pixel ref which we have already copied and the appropriate pixel ref
offset.

Turn SampleDrawBitmap into a GM to test this functionality.

Review URL: https://codereview.appspot.com/6348059

git-svn-id: http://skia.googlecode.com/svn/trunk@4417 2bbb7eff-a529-9590-31e7-b0007b416f81

gm/extractbitmap.cpp [new file with mode: 0644]
gyp/SampleApp.gyp
gyp/gmslides.gypi
samplecode/SampleDrawBitmap.cpp [deleted file]
src/pipe/SkGPipeWrite.cpp

diff --git a/gm/extractbitmap.cpp b/gm/extractbitmap.cpp
new file mode 100644 (file)
index 0000000..5002f1b
--- /dev/null
@@ -0,0 +1,86 @@
+
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "gm.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkDevice.h"
+#include "SkString.h"
+
+namespace skiagm {
+
+static void create_bitmap(SkBitmap* bitmap) {
+    const int W = 100;
+    const int H = 100;
+    bitmap->setConfig(SkBitmap::kARGB_8888_Config, W, H);
+    bitmap->allocPixels();
+
+    SkCanvas canvas(*bitmap);
+    canvas.drawColor(SK_ColorRED);
+    SkPaint paint;
+    paint.setColor(SK_ColorBLUE);
+    canvas.drawCircle(SkIntToScalar(W)/2, SkIntToScalar(H)/2, SkIntToScalar(W)/2, paint);
+}
+
+class ExtractBitmapGM : public GM {
+public:
+    ExtractBitmapGM() {}
+    
+protected:
+    // overrides from SkEventSink
+    virtual SkString onShortName() SK_OVERRIDE {
+        return SkString("extractbitmap");
+    }
+
+    virtual SkISize onISize() SK_OVERRIDE {
+        return make_isize(600, 600);
+    }
+
+    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+        SkBitmap bitmap;
+        create_bitmap(&bitmap);
+        int x = bitmap.width() / 2;
+        int y = bitmap.height() / 2;
+        SkBitmap subset;
+        bitmap.extractSubset(&subset, SkIRect::MakeXYWH(x, y, x, y));
+
+        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
+
+        canvas->drawBitmap(bitmap, 0, 0);
+        canvas->drawBitmap(subset, 0, 0);
+
+        // Now do the same but with a device bitmap as source image
+        SkRefPtr<SkDevice> primaryDevice(canvas->getDevice());
+        SkRefPtr<SkDevice> secondDevice(canvas->createCompatibleDevice(
+            SkBitmap::kARGB_8888_Config, bitmap.width(), 
+            bitmap.height(), true));
+        secondDevice->unref();
+        SkCanvas secondCanvas(secondDevice.get());
+        secondCanvas.writePixels(bitmap, 0, 0);
+
+        SkBitmap deviceBitmap = secondDevice->accessBitmap(false);
+        SkBitmap deviceSubset;
+        deviceBitmap.extractSubset(&deviceSubset, 
+             SkIRect::MakeXYWH(x, y, x, y));
+
+        canvas->translate(SkIntToScalar(120), SkIntToScalar(0));
+
+        canvas->drawBitmap(deviceBitmap, 0, 0);
+        canvas->drawBitmap(deviceSubset, 0, 0);
+
+    }
+    
+private:
+    typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+static GM* MyFactory(void*) { return new ExtractBitmapGM; }
+static GMRegistry reg(MyFactory);
+
+}
index 4f0ad5122224a885d102bb260bd16e48c3e0e29b..bc128be28df2bebed1e8c4885163a9ae61b81915 100644 (file)
@@ -48,7 +48,6 @@
         '../samplecode/SampleDegenerateTwoPtRadials.cpp',
         '../samplecode/SampleDither.cpp',
         '../samplecode/SampleDitherBitmap.cpp',
-        '../samplecode/SampleDrawBitmap.cpp',
         '../samplecode/SampleDrawLooper.cpp',
         '../samplecode/SampleEffects.cpp',
         '../samplecode/SampleEmboss.cpp',
index 7c648441d18b23c7e7a1fad3d32db018a94be481..45dab51a9b4a243e4679acde86e313447f300150 100644 (file)
@@ -20,6 +20,7 @@
     '../gm/degeneratesegments.cpp',
     '../gm/dashing.cpp',
     '../gm/drawbitmaprect.cpp',
+    '../gm/extractbitmap.cpp',
     '../gm/emptypath.cpp',
     '../gm/filltypes.cpp',
     '../gm/filltypespersp.cpp',
diff --git a/samplecode/SampleDrawBitmap.cpp b/samplecode/SampleDrawBitmap.cpp
deleted file mode 100644 (file)
index aaf1123..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include "SampleCode.h"
-#include "SkView.h"
-#include "SkCanvas.h"
-#include "SkShader.h"
-#include "SkUtils.h"
-#include "SkDevice.h"
-
-static void create_bitmap(SkBitmap* bitmap) {
-    const int W = 100;
-    const int H = 100;
-    bitmap->setConfig(SkBitmap::kARGB_8888_Config, W, H);
-    bitmap->allocPixels();
-
-    SkCanvas canvas(*bitmap);
-    canvas.drawColor(SK_ColorRED);
-    SkPaint paint;
-    paint.setColor(SK_ColorBLUE);
-    canvas.drawCircle(SkIntToScalar(W)/2, SkIntToScalar(H)/2, SkIntToScalar(W)/2, paint);
-}
-
-class DrawBitmapView : public SampleView {
-    SkPath fPath;
-public:
-       DrawBitmapView() {}
-    
-protected:
-    // overrides from SkEventSink
-    virtual bool onQuery(SkEvent* evt) {
-        if (SampleCode::TitleQ(*evt)) {
-            SampleCode::TitleR(evt, "DrawBitmap");
-            return true;
-        }
-        return this->INHERITED::onQuery(evt);
-    }
-    
-    virtual void onDrawContent(SkCanvas* canvas) {
-        SkBitmap bitmap;
-        create_bitmap(&bitmap);
-        int x = bitmap.width() / 2;
-        int y = bitmap.height() / 2;
-        SkBitmap subset;
-        bitmap.extractSubset(&subset, SkIRect::MakeXYWH(x, y, x, y));
-
-        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
-
-        canvas->drawBitmap(bitmap, 0, 0);
-        canvas->drawBitmap(subset, 0, 0);
-
-        // Now do the same but with a device bitmap as source image
-        SkRefPtr<SkDevice> primaryDevice(canvas->getDevice());
-        SkRefPtr<SkDevice> secondDevice(canvas->createCompatibleDevice(
-            SkBitmap::kARGB_8888_Config, bitmap.width(), 
-            bitmap.height(), true));
-        secondDevice->unref();
-        SkCanvas secondCanvas(secondDevice.get());
-        secondCanvas.writePixels(bitmap, 0, 0);
-
-        SkBitmap deviceBitmap = secondDevice->accessBitmap(false);
-        SkBitmap deviceSubset;
-        deviceBitmap.extractSubset(&deviceSubset, 
-             SkIRect::MakeXYWH(x, y, x, y));
-
-        canvas->translate(SkIntToScalar(120), SkIntToScalar(0));
-
-        canvas->drawBitmap(deviceBitmap, 0, 0);
-        canvas->drawBitmap(deviceSubset, 0, 0);
-
-    }
-    
-private:
-    typedef SampleView INHERITED;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-static SkView* MyFactory() { return new DrawBitmapView; }
-static SkViewRegister reg(MyFactory);
index 6b48bca530b907923aed508812bc2eb2d1965a7b..066159f10abe89f494ed8a6aa46c3f944fe73094 100644 (file)
@@ -81,10 +81,19 @@ public:
      * @return void* Pointer to the heap's copy of the bitmap. If NULL,
      *               the bitmap could not be copied.
      */
-    const SkBitmap* addBitmap(const SkBitmap& bm) {
-        const uint32_t genID = bm.getGenerationID();
+    const SkBitmap* addBitmap(const SkBitmap& orig) {
+        const uint32_t genID = orig.getGenerationID();
+        SkPixelRef* sharedPixelRef = NULL;
         for (int i = fBitmaps.count() - 1; i >= 0; i--) {
             if (genID == fBitmaps[i].fGenID) {
+                if (orig.pixelRefOffset() != fBitmaps[i].fBitmap->pixelRefOffset()) {
+                    // In this case, the bitmaps share a pixelRef, but have
+                    // different offsets. Keep track of the other bitmap so that
+                    // instead of making another copy of the pixelRef we can use
+                    // the copy we already made.
+                    sharedPixelRef = fBitmaps[i].fBitmap->pixelRef();
+                    break;
+                }
                 return fBitmaps[i].fBitmap;
             }
         }
@@ -92,13 +101,21 @@ public:
         // If the bitmap is mutable, we still need to do a deep copy, since the
         // caller may modify it afterwards. That said, if the bitmap is mutable,
         // but has no pixelRef, the copy constructor actually does a deep copy.
-        if (fCanDoShallowCopies && (bm.isImmutable() || !bm.pixelRef())) {
-            copy = new SkBitmap(bm);
+        if (fCanDoShallowCopies && (orig.isImmutable() || !orig.pixelRef())) {
+            copy = new SkBitmap(orig);
         } else {
-            copy = new SkBitmap();
-            if (!bm.copyTo(copy, bm.getConfig())) {
-                delete copy;
-                return NULL;
+            if (sharedPixelRef != NULL) {
+                // Do a shallow copy of the bitmap to get the width, height, etc
+                copy = new SkBitmap(orig);
+                // Replace the pixelRef with the copy that was already made, and
+                // use the appropriate offset.
+                copy->setPixelRef(sharedPixelRef, orig.pixelRefOffset());
+            } else {
+                copy = new SkBitmap();
+                if (!orig.copyTo(copy, orig.getConfig())) {
+                    delete copy;
+                    return NULL;
+                }
             }
         }
         BitmapInfo* info = fBitmaps.append();