Index: src/core/SkSpecialSurface.cpp |
diff --git a/src/core/SkSpecialSurface.cpp b/src/core/SkSpecialSurface.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4844f00d65301cff5dbfe4a72ea6547546cf1da4 |
--- /dev/null |
+++ b/src/core/SkSpecialSurface.cpp |
@@ -0,0 +1,155 @@ |
+/* |
+ * Copyright 2016 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file |
+ */ |
+ |
+#include "SkCanvas.h" |
+#include "SkSpecialImage.h" |
+#include "SkSpecialSurface.h" |
+#include "SkSurfacePriv.h" |
+ |
+ /////////////////////////////////////////////////////////////////////////////// |
+class SkSpecialSurface_Base : public SkSpecialSurface { |
+public: |
+ SkSpecialSurface_Base(int width, int height, const SkSurfaceProps* props) |
+ : INHERITED(width, height, props) |
+ , fCanvas(nullptr) { |
+ } |
+ |
+ virtual ~SkSpecialSurface_Base() { } |
+ |
+ // reset is called after an SkSpecialImage has been snapped |
+ void reset() { fCanvas.reset(); } |
+ |
+ // This can return nullptr if reset has already been called |
+ SkCanvas* onGetCanvas() { return fCanvas; } |
+ |
+ virtual SkSpecialImage* onNewImageSnapshot() = 0; |
+ |
+protected: |
+ SkAutoTUnref<SkCanvas> fCanvas; // initialized by derived classes in ctors |
+ |
+private: |
+ typedef SkSpecialSurface INHERITED; |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+static SkSpecialSurface_Base* as_SB(SkSpecialSurface* surface) { |
+ return static_cast<SkSpecialSurface_Base*>(surface); |
+} |
+ |
+SkSpecialSurface::SkSpecialSurface(int width, int height, const SkSurfaceProps* props) |
+ : fProps(SkSurfacePropsCopyOrDefault(props)), fWidth(width), fHeight(height) { |
+ SkASSERT(fWidth > 0); |
+ SkASSERT(fHeight > 0); |
+} |
+ |
+SkCanvas* SkSpecialSurface::getCanvas() { |
+ return as_SB(this)->onGetCanvas(); |
+} |
+ |
+SkSpecialImage* SkSpecialSurface::newImageSnapshot() { |
+ SkSpecialImage* image = as_SB(this)->onNewImageSnapshot(); |
+ as_SB(this)->reset(); |
+ return SkSafeRef(image); // the caller will call unref() to balance this |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+#include "SkMallocPixelRef.h" |
+ |
+class SkSpecialSurface_Raster : public SkSpecialSurface_Base { |
+public: |
+ SkSpecialSurface_Raster(SkPixelRef* pr, const SkSurfaceProps* props) |
+ : INHERITED(pr->info().width(), pr->info().height(), props) { |
+ const SkImageInfo& info = pr->info(); |
+ |
+ fBitmap.setInfo(info, info.minRowBytes()); |
+ fBitmap.setPixelRef(pr); |
+ |
+ fCanvas.reset(new SkCanvas(fBitmap)); |
+ } |
+ |
+ ~SkSpecialSurface_Raster() override { } |
+ |
+ SkSpecialImage* onNewImageSnapshot() override { |
+ return SkSpecialImage::New(this->width(), this->height(), fBitmap); |
+ } |
+ |
+private: |
+ SkBitmap fBitmap; |
+ |
+ typedef SkSpecialSurface_Base INHERITED; |
+}; |
+ |
+SkSpecialSurface* SkSpecialSurface::New(const SkImageInfo& info, const SkSurfaceProps* props) { |
+ SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewZeroed(info, 0, nullptr)); |
+ if (nullptr == pr.get()) { |
+ return nullptr; |
+ } |
+ |
+ return new SkSpecialSurface_Raster(pr, props); |
+} |
+ |
+#if SK_SUPPORT_GPU |
+/////////////////////////////////////////////////////////////////////////////// |
+#include "GrContext.h" |
+#include "SkGpuDevice.h" |
+ |
+class SkSpecialSurface_Gpu : public SkSpecialSurface_Base { |
+public: |
+ SkSpecialSurface_Gpu(GrContext* context, const GrSurfaceDesc& desc, const SkSurfaceProps* props) |
+ : INHERITED(desc.fWidth, desc.fHeight, props) { |
+ if (!context) { |
+ return; |
+ } |
+ |
+ if (!SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag)) { |
+ return; |
+ } |
+ |
+ fTexture.reset(context->textureProvider()->createApproxTexture(desc)); |
+ if (!fTexture) { |
+ return; |
+ } |
+ |
+ SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(fTexture->asRenderTarget(), props, |
+ SkGpuDevice::kUninit_InitContents)); |
+ if (!device) { |
+ return; |
+ } |
+ |
+ fCanvas.reset(new SkCanvas(device)); |
+ } |
+ |
+ ~SkSpecialSurface_Gpu() override { } |
+ |
+ SkSpecialImage* onNewImageSnapshot() override { |
+ return SkSpecialImage::New(this->width(), this->height(), fTexture); |
+ } |
+ |
+private: |
+ SkAutoTUnref<GrTexture> fTexture; |
+ |
+ typedef SkSpecialSurface_Base INHERITED; |
+}; |
+ |
+SkSpecialSurface* SkSpecialSurface::New(GrContext* context, |
+ const GrSurfaceDesc& desc, |
+ const SkSurfaceProps* props) { |
+ if (!context) { |
+ return nullptr; |
+ } |
+ return new SkSpecialSurface_Gpu(context, desc, props); |
+} |
+ |
+#else |
+ |
+SkSpecialSurface* SkSpecialSurface::New(GrContext* context, |
+ const GrSurfaceDesc& desc, |
+ const SkSurfaceProps* props) { |
+ return nullptr; |
+} |
+ |
+#endif |