Add helper for creating a SkSurface from a client created texture.
authorbsalomon <bsalomon@google.com>
Wed, 8 Apr 2015 15:38:40 +0000 (08:38 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 8 Apr 2015 15:38:40 +0000 (08:38 -0700)
Review URL: https://codereview.chromium.org/1071603002

include/core/SkSurface.h
src/image/SkSurface.cpp
src/image/SkSurface_Gpu.cpp
tests/SurfaceTest.cpp

index a87ecce..2df9865 100644 (file)
@@ -93,6 +93,13 @@ public:
     static SkSurface* NewRenderTargetDirect(GrRenderTarget* target) {
         return NewRenderTargetDirect(target, NULL);
     }
+
+    /**
+     *  Used to wrap a pre-existing backend 3D API texture in a SkSurface. The kRenderTarget flag
+     *  must be set on GrBackendTextureDesc for this to succeed.
+     */
+    static SkSurface* NewWrappedRenderTarget(GrContext*, GrBackendTextureDesc,
+                                             const SkSurfaceProps*);
     
     /**
      *  Return a new surface whose contents will be drawn to an offscreen
index 2d3fa2b..a999973 100644 (file)
@@ -188,5 +188,9 @@ SkSurface* SkSurface::NewRenderTarget(GrContext*, Budgeted, const SkImageInfo&,
     return NULL;
 }
 
+SkSurface* SkSurface::NewWrappedRenderTarget(GrContext*, GrBackendTextureDesc,
+                                             const SkSurfaceProps*) {
+    return NULL;
+}
 
 #endif
index b94e4e3..ac2f7fe 100644 (file)
@@ -99,4 +99,24 @@ SkSurface* SkSurface::NewRenderTarget(GrContext* ctx, Budgeted budgeted, const S
     return SkNEW_ARGS(SkSurface_Gpu, (device));
 }
 
+SkSurface* SkSurface::NewWrappedRenderTarget(GrContext* context, GrBackendTextureDesc desc,
+                                             const SkSurfaceProps* props) {
+    if (NULL == context) {
+        return NULL;
+    }
+    if (!SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag)) {
+        return NULL;
+    }
+    SkAutoTUnref<GrSurface> surface(context->wrapBackendTexture(desc));
+    if (!surface) {
+        return NULL;
+    }
+    SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(surface->asRenderTarget(), props,
+                                                         SkGpuDevice::kNeedClear_Flag));
+    if (!device) {
+        return NULL;
+    }
+    return SkNEW_ARGS(SkSurface_Gpu, (device));
+}
+
 #endif
index 6142af9..a11d60f 100644 (file)
@@ -90,6 +90,45 @@ static void test_empty_surface(skiatest::Reporter* reporter, GrContext* ctx) {
     }
 }
 
+#if SK_SUPPORT_GPU
+static void test_wrapped_texture_surface(skiatest::Reporter* reporter, GrContext* ctx) {
+    if (NULL == ctx) {
+        return;
+    }
+    // Test the wrapped factory for SkSurface by creating a texture using ctx and then treat it as
+    // an external texture and wrap it in a SkSurface.
+
+    GrSurfaceDesc texDesc;
+    texDesc.fConfig = kRGBA_8888_GrPixelConfig;
+    texDesc.fFlags = kRenderTarget_GrSurfaceFlag;
+    texDesc.fWidth = texDesc.fHeight = 100;
+    texDesc.fSampleCnt = 0;
+    texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
+    SkAutoTUnref<GrSurface> dummySurface(ctx->createTexture(texDesc, false));
+
+    REPORTER_ASSERT(reporter, dummySurface && dummySurface->asTexture() &&
+                              dummySurface->asRenderTarget());
+    if (!dummySurface || !dummySurface->asTexture() || !dummySurface->asRenderTarget()) {
+        return;
+    }
+    
+    GrBackendObject textureHandle = dummySurface->asTexture()->getTextureHandle();
+
+    GrBackendTextureDesc wrappedDesc;
+    wrappedDesc.fConfig = dummySurface->config();
+    wrappedDesc.fWidth = dummySurface->width();
+    wrappedDesc.fHeight = dummySurface->height();
+    wrappedDesc.fOrigin = dummySurface->origin();
+    wrappedDesc.fSampleCnt = dummySurface->asRenderTarget()->numSamples();
+    wrappedDesc.fFlags = kRenderTarget_GrBackendTextureFlag;
+    wrappedDesc.fTextureHandle = textureHandle;
+
+    SkAutoTUnref<SkSurface> surface(SkSurface::NewWrappedRenderTarget(ctx, wrappedDesc, NULL));
+    REPORTER_ASSERT(reporter, surface);
+}
+#endif
+
+
 static void test_image(skiatest::Reporter* reporter) {
     SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
     size_t rowBytes = info.minRowBytes();
@@ -569,6 +608,7 @@ DEF_GPUTEST(Surface, reporter, factory) {
                 TestGetTexture(reporter, kGpuScratch_SurfaceType, context);
                 test_empty_surface(reporter, context);
                 test_surface_budget(reporter, context);
+                test_wrapped_texture_surface(reporter, context);
             }
         }
     }