aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2014-06-27 06:48:14 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-06-27 06:48:14 -0700
commit982542dce8acbd2f3e7642268b21e76b93230daf (patch)
tree6a7281a2f7b1bbcf20eac4691e71b7d35cb4a089
parent8c0c7b0bcdf17ff672a972748f692a41c22aa0a1 (diff)
add SkSurface::NewRasterDirectReleaseProc
allows for lifetime control of pixel memory on raster surface BUG=skia: R=fmalita@google.com, bsalomon@google.com, fmalita@chromium.org Author: reed@google.com Review URL: https://codereview.chromium.org/351373005
-rw-r--r--include/core/SkSurface.h8
-rw-r--r--src/image/SkSurface_Raster.cpp23
-rw-r--r--tests/SurfaceTest.cpp18
3 files changed, 36 insertions, 13 deletions
diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h
index d049d8c040..68d4702cb5 100644
--- a/include/core/SkSurface.h
+++ b/include/core/SkSurface.h
@@ -38,6 +38,14 @@ public:
static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes);
/**
+ * The same as NewRasterDirect, but also accepts a call-back routine, which is invoked
+ * when the surface is deleted, and is passed the pixel memory and the specified context.
+ */
+ static SkSurface* NewRasterDirectReleaseProc(const SkImageInfo&, void* pixels, size_t rowBytes,
+ void (*releaseProc)(void* pixels, void* context),
+ void* context);
+
+ /**
* Return a new surface, with the memory for the pixels automatically
* allocated.
*
diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp
index 0b6efe19fe..986994ab8f 100644
--- a/src/image/SkSurface_Raster.cpp
+++ b/src/image/SkSurface_Raster.cpp
@@ -17,7 +17,8 @@ class SkSurface_Raster : public SkSurface_Base {
public:
static bool Valid(const SkImageInfo&, size_t rb = kIgnoreRowBytesValue);
- SkSurface_Raster(const SkImageInfo&, void*, size_t rb);
+ SkSurface_Raster(const SkImageInfo&, void*, size_t rb,
+ void (*releaseProc)(void* pixels, void* context), void* context);
SkSurface_Raster(SkPixelRef*);
virtual SkCanvas* onNewCanvas() SK_OVERRIDE;
@@ -76,10 +77,11 @@ bool SkSurface_Raster::Valid(const SkImageInfo& info, size_t rowBytes) {
return true;
}
-SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t rb)
+SkSurface_Raster::SkSurface_Raster(const SkImageInfo& info, void* pixels, size_t rb,
+ void (*releaseProc)(void* pixels, void* context), void* context)
: INHERITED(info)
{
- fBitmap.installPixels(info, pixels, rb);
+ fBitmap.installPixels(info, pixels, rb, NULL, releaseProc, context);
fWeOwnThePixels = false; // We are "Direct"
}
@@ -136,15 +138,24 @@ void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) {
///////////////////////////////////////////////////////////////////////////////
-SkSurface* SkSurface::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) {
- if (!SkSurface_Raster::Valid(info, rowBytes)) {
+SkSurface* SkSurface::NewRasterDirectReleaseProc(const SkImageInfo& info, void* pixels, size_t rb,
+ void (*releaseProc)(void* pixels, void* context),
+ void* context) {
+ if (NULL == releaseProc) {
+ context = NULL;
+ }
+ if (!SkSurface_Raster::Valid(info, rb)) {
return NULL;
}
if (NULL == pixels) {
return NULL;
}
+
+ return SkNEW_ARGS(SkSurface_Raster, (info, pixels, rb, releaseProc, context));
+}
- return SkNEW_ARGS(SkSurface_Raster, (info, pixels, rowBytes));
+SkSurface* SkSurface::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) {
+ return NewRasterDirectReleaseProc(info, pixels, rowBytes, NULL, NULL);
}
SkSurface* SkSurface::NewRaster(const SkImageInfo& info) {
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 3f61f89abe..610e3370f6 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -27,13 +27,14 @@ enum SurfaceType {
kGpuScratch_SurfaceType,
};
-static const int gSurfaceSize = 10;
-static SkPMColor gSurfaceStorage[gSurfaceSize * gSurfaceSize];
+static void release_storage(void* pixels, void* context) {
+ SkASSERT(pixels == context);
+ sk_free(pixels);
+}
static SkSurface* createSurface(SurfaceType surfaceType, GrContext* context,
SkImageInfo* requestedInfo = NULL) {
- static const SkImageInfo info = SkImageInfo::MakeN32Premul(gSurfaceSize,
- gSurfaceSize);
+ static const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
if (requestedInfo) {
*requestedInfo = info;
@@ -42,9 +43,12 @@ static SkSurface* createSurface(SurfaceType surfaceType, GrContext* context,
switch (surfaceType) {
case kRaster_SurfaceType:
return SkSurface::NewRaster(info);
- case kRasterDirect_SurfaceType:
- return SkSurface::NewRasterDirect(info, gSurfaceStorage,
- info.minRowBytes());
+ case kRasterDirect_SurfaceType: {
+ const size_t rowBytes = info.minRowBytes();
+ void* storage = sk_malloc_throw(info.getSafeSize(rowBytes));
+ return SkSurface::NewRasterDirectReleaseProc(info, storage, rowBytes,
+ release_storage, storage);
+ }
case kGpu_SurfaceType:
#if SK_SUPPORT_GPU
return context ? SkSurface::NewRenderTarget(context, info) : NULL;