1/* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file 6 */ 7 8#include "SkCanvas.h" 9#include "SkSpecialImage.h" 10#include "SkSpecialSurface.h" 11#include "SkSurfacePriv.h" 12 13 /////////////////////////////////////////////////////////////////////////////// 14class SkSpecialSurface_Base : public SkSpecialSurface { 15public: 16 SkSpecialSurface_Base(SkImageFilter::Proxy* proxy, 17 const SkIRect& subset, const SkSurfaceProps* props) 18 : INHERITED(proxy, subset, props) 19 , fCanvas(nullptr) { 20 } 21 22 virtual ~SkSpecialSurface_Base() { } 23 24 // reset is called after an SkSpecialImage has been snapped 25 void reset() { fCanvas.reset(); } 26 27 // This can return nullptr if reset has already been called or something when wrong in the ctor 28 SkCanvas* onGetCanvas() { return fCanvas; } 29 30 virtual SkSpecialImage* onNewImageSnapshot() = 0; 31 32protected: 33 SkAutoTUnref<SkCanvas> fCanvas; // initialized by derived classes in ctors 34 35private: 36 typedef SkSpecialSurface INHERITED; 37}; 38 39/////////////////////////////////////////////////////////////////////////////// 40static SkSpecialSurface_Base* as_SB(SkSpecialSurface* surface) { 41 return static_cast<SkSpecialSurface_Base*>(surface); 42} 43 44SkSpecialSurface::SkSpecialSurface(SkImageFilter::Proxy* proxy, 45 const SkIRect& subset, 46 const SkSurfaceProps* props) 47 : fProps(SkSurfacePropsCopyOrDefault(props)) 48 , fSubset(subset) 49 , fProxy(proxy) { 50 SkASSERT(fSubset.width() > 0); 51 SkASSERT(fSubset.height() > 0); 52} 53 54SkCanvas* SkSpecialSurface::getCanvas() { 55 return as_SB(this)->onGetCanvas(); 56} 57 58SkSpecialImage* SkSpecialSurface::newImageSnapshot() { 59 SkSpecialImage* image = as_SB(this)->onNewImageSnapshot(); 60 as_SB(this)->reset(); 61 return image; // the caller gets the creation ref 62} 63 64/////////////////////////////////////////////////////////////////////////////// 65#include "SkMallocPixelRef.h" 66 67class SkSpecialSurface_Raster : public SkSpecialSurface_Base { 68public: 69 SkSpecialSurface_Raster(SkImageFilter::Proxy* proxy, 70 SkPixelRef* pr, 71 const SkIRect& subset, 72 const SkSurfaceProps* props) 73 : INHERITED(proxy, subset, props) { 74 const SkImageInfo& info = pr->info(); 75 76 fBitmap.setInfo(info, info.minRowBytes()); 77 fBitmap.setPixelRef(pr); 78 79 fCanvas.reset(new SkCanvas(fBitmap)); 80 } 81 82 ~SkSpecialSurface_Raster() override { } 83 84 SkSpecialImage* onNewImageSnapshot() override { 85 return SkSpecialImage::NewFromRaster(this->proxy(), this->subset(), fBitmap); 86 } 87 88private: 89 SkBitmap fBitmap; 90 91 typedef SkSpecialSurface_Base INHERITED; 92}; 93 94SkSpecialSurface* SkSpecialSurface::NewFromBitmap(SkImageFilter::Proxy* proxy, 95 const SkIRect& subset, SkBitmap& bm, 96 const SkSurfaceProps* props) { 97 return new SkSpecialSurface_Raster(proxy, bm.pixelRef(), subset, props); 98} 99 100SkSpecialSurface* SkSpecialSurface::NewRaster(SkImageFilter::Proxy* proxy, 101 const SkImageInfo& info, 102 const SkSurfaceProps* props) { 103 SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewZeroed(info, 0, nullptr)); 104 if (nullptr == pr.get()) { 105 return nullptr; 106 } 107 108 const SkIRect subset = SkIRect::MakeWH(pr->info().width(), pr->info().height()); 109 110 return new SkSpecialSurface_Raster(proxy, pr, subset, props); 111} 112 113#if SK_SUPPORT_GPU 114/////////////////////////////////////////////////////////////////////////////// 115#include "GrContext.h" 116#include "SkGpuDevice.h" 117 118class SkSpecialSurface_Gpu : public SkSpecialSurface_Base { 119public: 120 SkSpecialSurface_Gpu(SkImageFilter::Proxy* proxy, 121 GrTexture* texture, 122 const SkIRect& subset, 123 const SkSurfaceProps* props) 124 : INHERITED(proxy, subset, props) 125 , fTexture(SkRef(texture)) { 126 127 SkASSERT(fTexture->asRenderTarget()); 128 129 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(fTexture->asRenderTarget(), props, 130 SkGpuDevice::kUninit_InitContents)); 131 if (!device) { 132 return; 133 } 134 135 fCanvas.reset(new SkCanvas(device)); 136 } 137 138 ~SkSpecialSurface_Gpu() override { } 139 140 SkSpecialImage* onNewImageSnapshot() override { 141 return SkSpecialImage::NewFromGpu(this->proxy(), this->subset(), 142 kNeedNewImageUniqueID_SpecialImage, fTexture); 143 } 144 145private: 146 SkAutoTUnref<GrTexture> fTexture; 147 148 typedef SkSpecialSurface_Base INHERITED; 149}; 150 151SkSpecialSurface* SkSpecialSurface::NewFromTexture(SkImageFilter::Proxy* proxy, 152 const SkIRect& subset, 153 GrTexture* texture, 154 const SkSurfaceProps* props) { 155 if (!texture->asRenderTarget()) { 156 return nullptr; 157 } 158 159 return new SkSpecialSurface_Gpu(proxy, texture, subset, props); 160} 161 162SkSpecialSurface* SkSpecialSurface::NewRenderTarget(SkImageFilter::Proxy* proxy, 163 GrContext* context, 164 const GrSurfaceDesc& desc, 165 const SkSurfaceProps* props) { 166 if (!context || !SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag)) { 167 return nullptr; 168 } 169 170 SkAutoTUnref<GrTexture> temp(context->textureProvider()->createApproxTexture(desc)); 171 if (!temp) { 172 return nullptr; 173 } 174 175 const SkIRect subset = SkIRect::MakeWH(desc.fWidth, desc.fHeight); 176 177 return new SkSpecialSurface_Gpu(proxy, temp, subset, props); 178} 179 180#else 181 182SkSpecialSurface* SkSpecialSurface::NewFromTexture(SkImageFilter::Proxy* proxy, 183 const SkIRect& subset, 184 GrTexture*, 185 const SkSurfaceProps*) { 186 return nullptr; 187} 188 189SkSpecialSurface* SkSpecialSurface::NewRenderTarget(SkImageFilter::Proxy* proxy, 190 GrContext* context, 191 const GrSurfaceDesc& desc, 192 const SkSurfaceProps* props) { 193 return nullptr; 194} 195 196#endif 197