Bug 854556 - Only hold SkCanvas in DrawTargetSkia r=mattwoodword
authorJames Willcox <snorp@snorp.net>
Wed, 29 May 2013 12:49:40 -0400
changeset 144808 a35e0a08ef37d4c6d1730c0dbf19ffb1d933e07b
parent 144807 136b751cffc7129fbc490c6809ed6b716e39ab10
child 144809 dd394e3894ac45567abf982be4cd304ddc2c359a
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodword
bugs854556
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 854556 - Only hold SkCanvas in DrawTargetSkia r=mattwoodword
gfx/2d/DrawTargetSkia.cpp
gfx/2d/DrawTargetSkia.h
gfx/2d/SourceSurfaceSkia.cpp
gfx/2d/SourceSurfaceSkia.h
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -94,19 +94,20 @@ DrawTargetSkia::~DrawTargetSkia()
     mSnapshots.clear();
   }
 }
 
 TemporaryRef<SourceSurface>
 DrawTargetSkia::Snapshot()
 {
   RefPtr<SourceSurfaceSkia> source = new SourceSurfaceSkia();
-  if (!source->InitWithBitmap(mBitmap, mFormat, this)) {
+
+  if (!source->InitFromCanvas(mCanvas.get(), mFormat, this))
     return nullptr;
-  }
+
   AppendSnapshot(source);
   return source;
 }
 
 void SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0)
 {
   switch (aPattern.GetType()) {
     case PATTERN_COLOR: {
@@ -546,58 +547,59 @@ DrawTargetSkia::CreateSourceSurfaceFromN
 
 void
 DrawTargetSkia::CopySurface(SourceSurface *aSurface,
                             const IntRect& aSourceRect,
                             const IntPoint &aDestination)
 {
   //TODO: We could just use writePixels() here if the sourceRect is the entire source
   
-    if (aSurface->GetType() != SURFACE_SKIA) {
+  if (aSurface->GetType() != SURFACE_SKIA) {
     return;
   }
 
   MarkChanged();
   
   const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(aSurface)->GetBitmap();
 
   mCanvas->save();
   mCanvas->resetMatrix();
   SkRect dest = IntRectToSkRect(IntRect(aDestination.x, aDestination.y, aSourceRect.width, aSourceRect.height)); 
   SkIRect source = IntRectToSkIRect(aSourceRect);
   mCanvas->clipRect(dest, SkRegion::kReplace_Op);
   SkPaint paint;
 
-  if (mBitmap.config() == SkBitmap::kRGB_565_Config &&
-      mCanvas->getDevice()->config() == SkBitmap::kRGB_565_Config) {
+  if (mCanvas->getDevice()->config() == SkBitmap::kRGB_565_Config) {
     // Set the xfermode to SOURCE_OVER to workaround
     // http://code.google.com/p/skia/issues/detail?id=628
     // RGB565 is opaque so they're equivalent anyway
     paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
   } else {
     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
   }
 
   mCanvas->drawBitmapRect(bitmap, &source, dest, &paint);
   mCanvas->restore();
 }
 
 bool
 DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat)
 {
-  mBitmap.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height);
-  if (!mBitmap.allocPixels()) {
+  SkAutoTUnref<SkDevice> device(new SkDevice(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height));
+
+  SkBitmap bitmap = device->accessBitmap(true);
+  if (!bitmap.allocPixels()) {
     return false;
   }
-  mBitmap.eraseARGB(0, 0, 0, 0);
-  SkAutoTUnref<SkDevice> device(new SkDevice(mBitmap));
+
+  bitmap.eraseARGB(0, 0, 0, 0);
+
   SkAutoTUnref<SkCanvas> canvas(new SkCanvas(device.get()));
   mSize = aSize;
 
-  mDevice = device.get();
   mCanvas = canvas.get();
   mFormat = aFormat;
   return true;
 }
 
 #ifdef USE_SKIA_GPU
 void
 DrawTargetSkia::InitWithFBO(unsigned int aFBOID, GrContext* aGrContext, const IntSize &aSize, SurfaceFormat aFormat)
@@ -611,39 +613,43 @@ DrawTargetSkia::InitWithFBO(unsigned int
   targetDescriptor.fRenderTargetHandle = aFBOID;
 
   SkAutoTUnref<GrRenderTarget> target(aGrContext->createPlatformRenderTarget(targetDescriptor));
 
   SkAutoTUnref<SkDevice> device(new SkGpuDevice(aGrContext, target.get()));
   SkAutoTUnref<SkCanvas> canvas(new SkCanvas(device.get()));
   mSize = aSize;
 
-  mDevice = device.get();
   mCanvas = canvas.get();
   mFormat = aFormat;
 }
 #endif
 
 void
 DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat)
 {
+  bool isOpaque = false;
   if (aFormat == FORMAT_B8G8R8X8) {
     // We have to manually set the A channel to be 255 as Skia doesn't understand BGRX
     ConvertBGRXToBGRA(aData, aSize, aStride);
-    mBitmap.setIsOpaque(true);
+    isOpaque = true;
   }
+  
+  SkAutoTUnref<SkDevice> device(new SkDevice(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, isOpaque));
 
-  mBitmap.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, aStride);
-  mBitmap.setPixels(aData);
-  
-  SkAutoTUnref<SkDevice> device(new SkDevice(mBitmap));
+  SkBitmap bitmap = (SkBitmap)device->accessBitmap(true);
+  bitmap.lockPixels();
+  bitmap.setPixels(aData);
+  bitmap.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, aStride);
+  bitmap.unlockPixels();
+  bitmap.notifyPixelsChanged();
+
   SkAutoTUnref<SkCanvas> canvas(new SkCanvas(device.get()));
   mSize = aSize;
 
-  mDevice = device.get();
   mCanvas = canvas.get();
   mFormat = aFormat;
 }
 
 void
 DrawTargetSkia::SetTransform(const Matrix& aTransform)
 {
   SkMatrix mat;
--- a/gfx/2d/DrawTargetSkia.h
+++ b/gfx/2d/DrawTargetSkia.h
@@ -97,24 +97,23 @@ public:
   void InitWithFBO(unsigned int aFBOID, GrContext* aGrContext, const IntSize &aSize, SurfaceFormat aFormat);
 #endif
   
   operator std::string() const {
     std::stringstream stream;
     stream << "DrawTargetSkia(" << this << ")";
     return stream.str();
   }
+
 private:
   friend class SourceSurfaceSkia;
   void AppendSnapshot(SourceSurfaceSkia* aSnapshot);
   void RemoveSnapshot(SourceSurfaceSkia* aSnapshot);
 
   void MarkChanged();
 
   IntSize mSize;
-  SkBitmap mBitmap;
   SkRefPtr<SkCanvas> mCanvas;
-  SkRefPtr<SkDevice> mDevice;
   std::vector<SourceSurfaceSkia*> mSnapshots;
 };
 
 }
 }
--- a/gfx/2d/SourceSurfaceSkia.cpp
+++ b/gfx/2d/SourceSurfaceSkia.cpp
@@ -31,16 +31,33 @@ SourceSurfaceSkia::GetSize() const
 }
 
 SurfaceFormat
 SourceSurfaceSkia::GetFormat() const
 {
   return mFormat;
 }
 
+bool
+SourceSurfaceSkia::InitFromCanvas(SkCanvas* aCanvas,
+                                  SurfaceFormat aFormat,
+                                  DrawTargetSkia* aOwner)
+{
+  SkISize size = aCanvas->getDeviceSize();
+
+  mBitmap = (SkBitmap)aCanvas->getDevice()->accessBitmap(false);
+  mFormat = aFormat;
+
+  mSize = IntSize(size.fWidth, size.fHeight);
+  mStride = mBitmap.rowBytes();
+  mDrawTarget = aOwner;
+
+  return true;
+}
+
 bool 
 SourceSurfaceSkia::InitFromData(unsigned char* aData,
                                 const IntSize &aSize,
                                 int32_t aStride,
                                 SurfaceFormat aFormat)
 {
   SkBitmap temp;
   temp.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, aStride);
@@ -60,36 +77,16 @@ SourceSurfaceSkia::InitFromData(unsigned
   }
 
   mSize = aSize;
   mFormat = aFormat;
   mStride = aStride;
   return true;
 }
 
-bool
-SourceSurfaceSkia::InitWithBitmap(const SkBitmap& aBitmap,
-                                  SurfaceFormat aFormat,
-                                  DrawTargetSkia* aOwner)
-{
-  mFormat = aFormat;
-  mSize = IntSize(aBitmap.width(), aBitmap.height());
-
-  if (aOwner) {
-    mBitmap = aBitmap;
-    mStride = aBitmap.rowBytes();
-    mDrawTarget = aOwner;
-    return true;
-  } else if (aBitmap.copyTo(&mBitmap, aBitmap.getConfig())) {
-    mStride = mBitmap.rowBytes();
-    return true;
-  }
-  return false;
-}
-
 unsigned char*
 SourceSurfaceSkia::GetData()
 {
   mBitmap.lockPixels();
   unsigned char *pixels = (unsigned char *)mBitmap.getPixels();
   mBitmap.unlockPixels();
   return pixels;
 
--- a/gfx/2d/SourceSurfaceSkia.h
+++ b/gfx/2d/SourceSurfaceSkia.h
@@ -28,25 +28,20 @@ public:
 
   SkBitmap& GetBitmap() { return mBitmap; }
 
   bool InitFromData(unsigned char* aData,
                     const IntSize &aSize,
                     int32_t aStride,
                     SurfaceFormat aFormat);
 
-  /**
-   * If aOwner is nullptr, we make a copy of the pixel data in the bitmap, 
-   * otherwise we just reference this data until DrawTargetWillChange is called.
-   */
-  bool InitWithBitmap(const SkBitmap& aBitmap,
+  bool InitFromCanvas(SkCanvas* aCanvas,
                       SurfaceFormat aFormat,
                       DrawTargetSkia* aOwner);
 
-
   virtual unsigned char *GetData();
 
   virtual int32_t Stride() { return mStride; }
 
 private:
   friend class DrawTargetSkia;
 
   void DrawTargetWillChange();