| 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
|
|
|