1b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips/* 2b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips * Copyright 2016 Google Inc. 3b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips * 4b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips * Use of this source code is governed by a BSD-style license that can be 5b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips * found in the LICENSE file 6b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips */ 7b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 8b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips#include "SkCanvas.h" 9b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips#include "SkSpecialImage.h" 10b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips#include "SkSpecialSurface.h" 11b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips#include "SkSurfacePriv.h" 12b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 13b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips /////////////////////////////////////////////////////////////////////////////// 14b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipsclass SkSpecialSurface_Base : public SkSpecialSurface { 15b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipspublic: 163b087f4010327b304242aaf27ef3689150dfc226robertphillips SkSpecialSurface_Base(SkImageFilter::Proxy* proxy, 173b087f4010327b304242aaf27ef3689150dfc226robertphillips const SkIRect& subset, const SkSurfaceProps* props) 183b087f4010327b304242aaf27ef3689150dfc226robertphillips : INHERITED(proxy, subset, props) 19b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips , fCanvas(nullptr) { 20b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips } 21b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 22b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips virtual ~SkSpecialSurface_Base() { } 23b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 24b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips // reset is called after an SkSpecialImage has been snapped 25b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips void reset() { fCanvas.reset(); } 26b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 27b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips // This can return nullptr if reset has already been called or something when wrong in the ctor 28b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkCanvas* onGetCanvas() { return fCanvas; } 29b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 30b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips virtual SkSpecialImage* onNewImageSnapshot() = 0; 31b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 32b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipsprotected: 33b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkAutoTUnref<SkCanvas> fCanvas; // initialized by derived classes in ctors 34b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 35b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipsprivate: 36b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips typedef SkSpecialSurface INHERITED; 37b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips}; 38b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 39b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips/////////////////////////////////////////////////////////////////////////////// 40b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipsstatic SkSpecialSurface_Base* as_SB(SkSpecialSurface* surface) { 41b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips return static_cast<SkSpecialSurface_Base*>(surface); 42b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips} 43b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 443b087f4010327b304242aaf27ef3689150dfc226robertphillipsSkSpecialSurface::SkSpecialSurface(SkImageFilter::Proxy* proxy, 453b087f4010327b304242aaf27ef3689150dfc226robertphillips const SkIRect& subset, 463b087f4010327b304242aaf27ef3689150dfc226robertphillips const SkSurfaceProps* props) 47b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips : fProps(SkSurfacePropsCopyOrDefault(props)) 483b087f4010327b304242aaf27ef3689150dfc226robertphillips , fSubset(subset) 493b087f4010327b304242aaf27ef3689150dfc226robertphillips , fProxy(proxy) { 50b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkASSERT(fSubset.width() > 0); 51b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkASSERT(fSubset.height() > 0); 52b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips} 53b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 54b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipsSkCanvas* SkSpecialSurface::getCanvas() { 55b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips return as_SB(this)->onGetCanvas(); 56b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips} 57b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 58b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipsSkSpecialImage* SkSpecialSurface::newImageSnapshot() { 59b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkSpecialImage* image = as_SB(this)->onNewImageSnapshot(); 60b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips as_SB(this)->reset(); 6116aad786023e4cfa338b42a5f35d4f885defb789robertphillips return image; // the caller gets the creation ref 62b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips} 63b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 64b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips/////////////////////////////////////////////////////////////////////////////// 65b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips#include "SkMallocPixelRef.h" 66b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 67b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipsclass SkSpecialSurface_Raster : public SkSpecialSurface_Base { 68b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipspublic: 693b087f4010327b304242aaf27ef3689150dfc226robertphillips SkSpecialSurface_Raster(SkImageFilter::Proxy* proxy, 703b087f4010327b304242aaf27ef3689150dfc226robertphillips SkPixelRef* pr, 713b087f4010327b304242aaf27ef3689150dfc226robertphillips const SkIRect& subset, 723b087f4010327b304242aaf27ef3689150dfc226robertphillips const SkSurfaceProps* props) 733b087f4010327b304242aaf27ef3689150dfc226robertphillips : INHERITED(proxy, subset, props) { 74b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips const SkImageInfo& info = pr->info(); 75b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 76b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips fBitmap.setInfo(info, info.minRowBytes()); 77b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips fBitmap.setPixelRef(pr); 78b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 79b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips fCanvas.reset(new SkCanvas(fBitmap)); 80b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips } 81b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 82b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips ~SkSpecialSurface_Raster() override { } 83b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 84b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkSpecialImage* onNewImageSnapshot() override { 853b087f4010327b304242aaf27ef3689150dfc226robertphillips return SkSpecialImage::NewFromRaster(this->proxy(), this->subset(), fBitmap); 86b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips } 87b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 88b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipsprivate: 89b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkBitmap fBitmap; 90b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 91b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips typedef SkSpecialSurface_Base INHERITED; 92b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips}; 93b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 943b087f4010327b304242aaf27ef3689150dfc226robertphillipsSkSpecialSurface* SkSpecialSurface::NewFromBitmap(SkImageFilter::Proxy* proxy, 953b087f4010327b304242aaf27ef3689150dfc226robertphillips const SkIRect& subset, SkBitmap& bm, 96b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips const SkSurfaceProps* props) { 973b087f4010327b304242aaf27ef3689150dfc226robertphillips return new SkSpecialSurface_Raster(proxy, bm.pixelRef(), subset, props); 98b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips} 99b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 1003b087f4010327b304242aaf27ef3689150dfc226robertphillipsSkSpecialSurface* SkSpecialSurface::NewRaster(SkImageFilter::Proxy* proxy, 1013b087f4010327b304242aaf27ef3689150dfc226robertphillips const SkImageInfo& info, 102b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips const SkSurfaceProps* props) { 103b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkAutoTUnref<SkPixelRef> pr(SkMallocPixelRef::NewZeroed(info, 0, nullptr)); 104b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips if (nullptr == pr.get()) { 105b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips return nullptr; 106b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips } 107b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 108b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips const SkIRect subset = SkIRect::MakeWH(pr->info().width(), pr->info().height()); 109b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 1103b087f4010327b304242aaf27ef3689150dfc226robertphillips return new SkSpecialSurface_Raster(proxy, pr, subset, props); 111b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips} 112b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 113b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips#if SK_SUPPORT_GPU 114b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips/////////////////////////////////////////////////////////////////////////////// 115b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips#include "GrContext.h" 116b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips#include "SkGpuDevice.h" 117b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 118b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipsclass SkSpecialSurface_Gpu : public SkSpecialSurface_Base { 119b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipspublic: 1203b087f4010327b304242aaf27ef3689150dfc226robertphillips SkSpecialSurface_Gpu(SkImageFilter::Proxy* proxy, 1213b087f4010327b304242aaf27ef3689150dfc226robertphillips GrTexture* texture, 1223b087f4010327b304242aaf27ef3689150dfc226robertphillips const SkIRect& subset, 1233b087f4010327b304242aaf27ef3689150dfc226robertphillips const SkSurfaceProps* props) 1243b087f4010327b304242aaf27ef3689150dfc226robertphillips : INHERITED(proxy, subset, props) 12516aad786023e4cfa338b42a5f35d4f885defb789robertphillips , fTexture(SkRef(texture)) { 126b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 127b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkASSERT(fTexture->asRenderTarget()); 128b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 129b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(fTexture->asRenderTarget(), props, 130b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkGpuDevice::kUninit_InitContents)); 131b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips if (!device) { 132b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips return; 133b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips } 134b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 135b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips fCanvas.reset(new SkCanvas(device)); 136b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips } 137b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 138b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips ~SkSpecialSurface_Gpu() override { } 139b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 140b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkSpecialImage* onNewImageSnapshot() override { 1413b087f4010327b304242aaf27ef3689150dfc226robertphillips return SkSpecialImage::NewFromGpu(this->proxy(), this->subset(), 1423b087f4010327b304242aaf27ef3689150dfc226robertphillips kNeedNewImageUniqueID_SpecialImage, fTexture); 143b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips } 144b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 145b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillipsprivate: 146b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips SkAutoTUnref<GrTexture> fTexture; 147b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 148b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips typedef SkSpecialSurface_Base INHERITED; 149b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips}; 150b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 1513b087f4010327b304242aaf27ef3689150dfc226robertphillipsSkSpecialSurface* SkSpecialSurface::NewFromTexture(SkImageFilter::Proxy* proxy, 1523b087f4010327b304242aaf27ef3689150dfc226robertphillips const SkIRect& subset, 1533b087f4010327b304242aaf27ef3689150dfc226robertphillips GrTexture* texture, 154b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips const SkSurfaceProps* props) { 155b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips if (!texture->asRenderTarget()) { 156b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips return nullptr; 157b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips } 158b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 1593b087f4010327b304242aaf27ef3689150dfc226robertphillips return new SkSpecialSurface_Gpu(proxy, texture, subset, props); 160b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips} 161b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 1623b087f4010327b304242aaf27ef3689150dfc226robertphillipsSkSpecialSurface* SkSpecialSurface::NewRenderTarget(SkImageFilter::Proxy* proxy, 1633b087f4010327b304242aaf27ef3689150dfc226robertphillips GrContext* context, 164b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips const GrSurfaceDesc& desc, 165b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips const SkSurfaceProps* props) { 166b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips if (!context || !SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag)) { 167b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips return nullptr; 168b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips } 169b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 17016aad786023e4cfa338b42a5f35d4f885defb789robertphillips SkAutoTUnref<GrTexture> temp(context->textureProvider()->createApproxTexture(desc)); 171b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips if (!temp) { 172b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips return nullptr; 173b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips } 174b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 175b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips const SkIRect subset = SkIRect::MakeWH(desc.fWidth, desc.fHeight); 176b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 1773b087f4010327b304242aaf27ef3689150dfc226robertphillips return new SkSpecialSurface_Gpu(proxy, temp, subset, props); 178b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips} 179b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 180b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips#else 181b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 1823b087f4010327b304242aaf27ef3689150dfc226robertphillipsSkSpecialSurface* SkSpecialSurface::NewFromTexture(SkImageFilter::Proxy* proxy, 1833b087f4010327b304242aaf27ef3689150dfc226robertphillips const SkIRect& subset, 1843b087f4010327b304242aaf27ef3689150dfc226robertphillips GrTexture*, 185b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips const SkSurfaceProps*) { 186b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips return nullptr; 187b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips} 188b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 1893b087f4010327b304242aaf27ef3689150dfc226robertphillipsSkSpecialSurface* SkSpecialSurface::NewRenderTarget(SkImageFilter::Proxy* proxy, 1903b087f4010327b304242aaf27ef3689150dfc226robertphillips GrContext* context, 191b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips const GrSurfaceDesc& desc, 192b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips const SkSurfaceProps* props) { 193b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips return nullptr; 194b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips} 195b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips 196b6c65e99956b867e24bd5bd68ae37673a9fd4b27robertphillips#endif 197