Bug 1057216 - Make DrawTargetCG hold a reference to DataSourceSurface when we're wrapping their data. r=jrmuizel
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 27 Aug 2014 10:20:18 +1200
changeset 223383 c9e48790f6fa33dd04dfa1ce0009a5658dc2a636
parent 223382 247755b96ab8513391ca537fbe82e24f68ac7167
child 223384 5ee7a98d1e2fe5fd290f23bad457a1b098331fa5
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1057216
milestone34.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 1057216 - Make DrawTargetCG hold a reference to DataSourceSurface when we're wrapping their data. r=jrmuizel
gfx/2d/DrawTargetCG.cpp
gfx/2d/SourceSurfaceCG.cpp
gfx/2d/SourceSurfaceCG.h
--- a/gfx/2d/DrawTargetCG.cpp
+++ b/gfx/2d/DrawTargetCG.cpp
@@ -210,16 +210,21 @@ DrawTargetCG::CreateSourceSurfaceFromDat
 
   if (!newSurf->InitFromData(aData, aSize, aStride, aFormat)) {
     return nullptr;
   }
 
   return newSurf.forget();
 }
 
+static void releaseDataSurface(void* info, const void *data, size_t size)
+{
+  static_cast<DataSourceSurface*>(info)->Release();
+}
+
 // This function returns a retained CGImage that needs to be released after
 // use. The reason for this is that we want to either reuse an existing CGImage
 // or create a new one.
 static CGImageRef
 GetRetainedImageFromSourceSurface(SourceSurface *aSurface)
 {
   switch(aSurface->GetType()) {
     case SurfaceType::COREGRAPHICS_IMAGE:
@@ -229,17 +234,19 @@ GetRetainedImageFromSourceSurface(Source
       return CGImageRetain(static_cast<SourceSurfaceCGContext*>(aSurface)->GetImage());
 
     default:
     {
       RefPtr<DataSourceSurface> data = aSurface->GetDataSurface();
       if (!data) {
         MOZ_CRASH("unsupported source surface");
       }
-      return CreateCGImage(nullptr, data->GetData(), data->GetSize(),
+      data->AddRef();
+      return CreateCGImage(releaseDataSurface, data.get(),
+                           data->GetData(), data->GetSize(),
                            data->Stride(), data->GetFormat());
     }
   }
 }
 
 TemporaryRef<SourceSurface>
 DrawTargetCG::OptimizeSourceSurface(SourceSurface *aSurface) const
 {
--- a/gfx/2d/SourceSurfaceCG.cpp
+++ b/gfx/2d/SourceSurfaceCG.cpp
@@ -54,16 +54,32 @@ static void releaseCallback(void *info, 
 
 CGImageRef
 CreateCGImage(void *aInfo,
               const void *aData,
               const IntSize &aSize,
               int32_t aStride,
               SurfaceFormat aFormat)
 {
+  return CreateCGImage(releaseCallback,
+                       aInfo,
+                       aData,
+                       aSize,
+                       aStride,
+                       aFormat);
+}
+
+CGImageRef
+CreateCGImage(CGDataProviderReleaseDataCallback aCallback,
+              void *aInfo,
+              const void *aData,
+              const IntSize &aSize,
+              int32_t aStride,
+              SurfaceFormat aFormat)
+{
   //XXX: we should avoid creating this colorspace everytime
   CGColorSpaceRef colorSpace = nullptr;
   CGBitmapInfo bitinfo = 0;
   int bitsPerComponent = 0;
   int bitsPerPixel = 0;
 
   switch (aFormat) {
     case SurfaceFormat::B8G8R8A8:
@@ -92,17 +108,17 @@ CreateCGImage(void *aInfo,
 
   size_t bufLen = BufferSizeFromStrideAndHeight(aStride, aSize.height);
   if (bufLen == 0) {
     return nullptr;
   }
   CGDataProviderRef dataProvider = CGDataProviderCreateWithData(aInfo,
                                                                 aData,
                                                                 bufLen,
-                                                                releaseCallback);
+                                                                aCallback);
 
   CGImageRef image;
   if (aFormat == SurfaceFormat::A8) {
     CGFloat decode[] = {1.0, 0.0};
     image = CGImageMaskCreate (aSize.width, aSize.height,
                                bitsPerComponent,
                                bitsPerPixel,
                                aStride,
--- a/gfx/2d/SourceSurfaceCG.h
+++ b/gfx/2d/SourceSurfaceCG.h
@@ -11,16 +11,24 @@
 #include "2D.h"
 
 class MacIOSurface;
 
 namespace mozilla {
 namespace gfx {
 
 CGImageRef
+CreateCGImage(CGDataProviderReleaseDataCallback aCallback,
+              void *aInfo,
+              const void *aData,
+              const IntSize &aSize,
+              int32_t aStride,
+              SurfaceFormat aFormat);
+
+CGImageRef
 CreateCGImage(void *aInfo,
               const void *aData,
               const IntSize &aSize,
               int32_t aStride,
               SurfaceFormat aFormat);
 
 class DrawTargetCG;