/**
* Call this if the contents are about to change. This will (lazily) force a new
* value to be returned from generationID() when it is called next.
+ *
+ * CAN WE DEPRECATE THIS?
*/
void notifyContentWillChange(ContentChangeMode mode);
+ enum TextureHandleAccess {
+ kFlushRead_TextureHandleAccess, //!< caller may read from the texture
+ kFlushWrite_TextureHandleAccess, //!< caller may write to the texture
+ kDiscardWrite_TextureHandleAccess, //!< caller must over-write the entire texture
+ };
+ /**
+ * Retrieves the backend API handle of the texture used by this surface, or 0 if the surface
+ * is not backed by a GPU texture.
+ *
+ * The returned texture-handle is only valid until the next draw-call into the surface,
+ * or the surface is deleted.
+ */
+ GrBackendObject getTextureHandle(TextureHandleAccess);
+
/**
* Return a canvas that will draw into this surface. This will always
* return the same canvas for a given surface, and is manged/owned by the
fDevice->unref();
}
+GrBackendObject SkSurface_Gpu::onGetTextureHandle(TextureHandleAccess access) {
+ GrRenderTarget* rt = fDevice->accessRenderTarget();
+ switch (access) {
+ case kFlushRead_TextureHandleAccess:
+ rt->prepareForExternalRead(); // todo: rename to prepareForExternalAccess()
+ break;
+ case kFlushWrite_TextureHandleAccess:
+ this->notifyContentWillChange(kRetain_ContentChangeMode);
+ rt->flushWrites();
+ break;
+ case kDiscardWrite_TextureHandleAccess:
+ this->notifyContentWillChange(kDiscard_ContentChangeMode);
+ rt->discard();
+ break;
+ }
+ return rt->asTexture()->getTextureHandle();
+}
+
SkCanvas* SkSurface_Gpu::onNewCanvas() {
SkCanvas::InitFlags flags = SkCanvas::kDefault_InitFlags;
// When we think this works...
}
};
-static SkImage* create_image(ImageType imageType, GrContext* context, SkColor color,
+static void test_texture_handle(skiatest::Reporter* reporter, SkSurface* surf) {
+ SkAutoTUnref<SkImage> image0(surf->newImageSnapshot());
+ GrBackendObject obj = surf->getTextureHandle(SkSurface::kFlushRead_TextureHandleAccess);
+ REPORTER_ASSERT(reporter, obj != 0);
+ SkAutoTUnref<SkImage> image1(surf->newImageSnapshot());
+ // just read access should not affect the snapshot
+ REPORTER_ASSERT(reporter, image0->uniqueID() == image1->uniqueID());
+
+ obj = surf->getTextureHandle(SkSurface::kFlushWrite_TextureHandleAccess);
+ REPORTER_ASSERT(reporter, obj != 0);
+ SkAutoTUnref<SkImage> image2(surf->newImageSnapshot());
+ // expect a new image, since we claimed we would write
+ REPORTER_ASSERT(reporter, image0->uniqueID() != image2->uniqueID());
+
+ obj = surf->getTextureHandle(SkSurface::kDiscardWrite_TextureHandleAccess);
+ REPORTER_ASSERT(reporter, obj != 0);
+ SkAutoTUnref<SkImage> image3(surf->newImageSnapshot());
+ // expect a new(er) image, since we claimed we would write
+ REPORTER_ASSERT(reporter, image0->uniqueID() != image3->uniqueID());
+ REPORTER_ASSERT(reporter, image2->uniqueID() != image3->uniqueID());
+}
+
+static SkImage* create_image(skiatest::Reporter* reporter,
+ ImageType imageType, GrContext* context, SkColor color,
ReleaseDataContext* releaseContext) {
const SkPMColor pmcolor = SkPreMultiplyColor(color);
const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
SkAutoTUnref<SkSurface> surf(
SkSurface::NewRenderTarget(context, SkSurface::kNo_Budgeted, info, 0));
surf->getCanvas()->clear(color);
+ // test our backing texture while were here...
+ test_texture_handle(reporter, surf);
+ // redraw so our returned image looks as expected.
+ surf->getCanvas()->clear(color);
return surf->newImageSnapshot();
}
case kCodec_ImageType: {
size_t rowBytes;
releaseCtx.fData = NULL;
- SkAutoTUnref<SkImage> image(create_image(gRec[i].fType, ctx, color, &releaseCtx));
+ SkAutoTUnref<SkImage> image(create_image(reporter, gRec[i].fType, ctx, color, &releaseCtx));
if (!image.get()) {
SkDebugf("failed to createImage[%d] %s\n", i, gRec[i].fName);
continue; // gpu may not be enabled