1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/core/SkSpecialSurface.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include <memory> 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 13cb93a386Sopenharmony_ci#include "src/core/SkSpecialImage.h" 14cb93a386Sopenharmony_ci#include "src/core/SkSurfacePriv.h" 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////////// 17cb93a386Sopenharmony_ciclass SkSpecialSurface_Base : public SkSpecialSurface { 18cb93a386Sopenharmony_cipublic: 19cb93a386Sopenharmony_ci SkSpecialSurface_Base(const SkIRect& subset, const SkSurfaceProps& props) 20cb93a386Sopenharmony_ci : INHERITED(subset, props) 21cb93a386Sopenharmony_ci , fCanvas(nullptr) { 22cb93a386Sopenharmony_ci } 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci // reset is called after an SkSpecialImage has been snapped 25cb93a386Sopenharmony_ci void reset() { fCanvas.reset(); } 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci // This can return nullptr if reset has already been called or something when wrong in the ctor 28cb93a386Sopenharmony_ci SkCanvas* onGetCanvas() { return fCanvas.get(); } 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci virtual sk_sp<SkSpecialImage> onMakeImageSnapshot() = 0; 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ciprotected: 33cb93a386Sopenharmony_ci std::unique_ptr<SkCanvas> fCanvas; // initialized by derived classes in ctors 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ciprivate: 36cb93a386Sopenharmony_ci using INHERITED = SkSpecialSurface; 37cb93a386Sopenharmony_ci}; 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////// 40cb93a386Sopenharmony_cistatic SkSpecialSurface_Base* as_SB(SkSpecialSurface* surface) { 41cb93a386Sopenharmony_ci return static_cast<SkSpecialSurface_Base*>(surface); 42cb93a386Sopenharmony_ci} 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ciSkSpecialSurface::SkSpecialSurface(const SkIRect& subset, 45cb93a386Sopenharmony_ci const SkSurfaceProps& props) 46cb93a386Sopenharmony_ci : fProps(props.flags(), kUnknown_SkPixelGeometry) 47cb93a386Sopenharmony_ci , fSubset(subset) { 48cb93a386Sopenharmony_ci SkASSERT(fSubset.width() > 0); 49cb93a386Sopenharmony_ci SkASSERT(fSubset.height() > 0); 50cb93a386Sopenharmony_ci} 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ciSkCanvas* SkSpecialSurface::getCanvas() { 53cb93a386Sopenharmony_ci return as_SB(this)->onGetCanvas(); 54cb93a386Sopenharmony_ci} 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_cisk_sp<SkSpecialImage> SkSpecialSurface::makeImageSnapshot() { 57cb93a386Sopenharmony_ci sk_sp<SkSpecialImage> image(as_SB(this)->onMakeImageSnapshot()); 58cb93a386Sopenharmony_ci as_SB(this)->reset(); 59cb93a386Sopenharmony_ci return image; // the caller gets the creation ref 60cb93a386Sopenharmony_ci} 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////// 63cb93a386Sopenharmony_ci#include "include/core/SkMallocPixelRef.h" 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ciclass SkSpecialSurface_Raster : public SkSpecialSurface_Base { 66cb93a386Sopenharmony_cipublic: 67cb93a386Sopenharmony_ci SkSpecialSurface_Raster(const SkImageInfo& info, 68cb93a386Sopenharmony_ci sk_sp<SkPixelRef> pr, 69cb93a386Sopenharmony_ci const SkIRect& subset, 70cb93a386Sopenharmony_ci const SkSurfaceProps& props) 71cb93a386Sopenharmony_ci : INHERITED(subset, props) { 72cb93a386Sopenharmony_ci SkASSERT(info.width() == pr->width() && info.height() == pr->height()); 73cb93a386Sopenharmony_ci fBitmap.setInfo(info, info.minRowBytes()); 74cb93a386Sopenharmony_ci fBitmap.setPixelRef(std::move(pr), 0, 0); 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ci fCanvas = std::make_unique<SkCanvas>(fBitmap, this->props()); 77cb93a386Sopenharmony_ci fCanvas->clipRect(SkRect::Make(subset)); 78cb93a386Sopenharmony_ci#ifdef SK_IS_BOT 79cb93a386Sopenharmony_ci fCanvas->clear(SK_ColorRED); // catch any imageFilter sloppiness 80cb93a386Sopenharmony_ci#endif 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ci ~SkSpecialSurface_Raster() override { } 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci sk_sp<SkSpecialImage> onMakeImageSnapshot() override { 86cb93a386Sopenharmony_ci return SkSpecialImage::MakeFromRaster(this->subset(), fBitmap, this->props()); 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ciprivate: 90cb93a386Sopenharmony_ci SkBitmap fBitmap; 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci using INHERITED = SkSpecialSurface_Base; 93cb93a386Sopenharmony_ci}; 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_cisk_sp<SkSpecialSurface> SkSpecialSurface::MakeFromBitmap(const SkIRect& subset, SkBitmap& bm, 96cb93a386Sopenharmony_ci const SkSurfaceProps& props) { 97cb93a386Sopenharmony_ci if (subset.isEmpty() || !SkSurfaceValidateRasterInfo(bm.info(), bm.rowBytes())) { 98cb93a386Sopenharmony_ci return nullptr; 99cb93a386Sopenharmony_ci } 100cb93a386Sopenharmony_ci return sk_make_sp<SkSpecialSurface_Raster>(bm.info(), sk_ref_sp(bm.pixelRef()), subset, props); 101cb93a386Sopenharmony_ci} 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_cisk_sp<SkSpecialSurface> SkSpecialSurface::MakeRaster(const SkImageInfo& info, 104cb93a386Sopenharmony_ci const SkSurfaceProps& props) { 105cb93a386Sopenharmony_ci if (!SkSurfaceValidateRasterInfo(info)) { 106cb93a386Sopenharmony_ci return nullptr; 107cb93a386Sopenharmony_ci } 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ci sk_sp<SkPixelRef> pr = SkMallocPixelRef::MakeAllocate(info, 0); 110cb93a386Sopenharmony_ci if (!pr) { 111cb93a386Sopenharmony_ci return nullptr; 112cb93a386Sopenharmony_ci } 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci const SkIRect subset = SkIRect::MakeWH(info.width(), info.height()); 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci return sk_make_sp<SkSpecialSurface_Raster>(info, std::move(pr), subset, props); 117cb93a386Sopenharmony_ci} 118cb93a386Sopenharmony_ci 119cb93a386Sopenharmony_ci#if SK_SUPPORT_GPU 120cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////// 121cb93a386Sopenharmony_ci#include "include/gpu/GrRecordingContext.h" 122cb93a386Sopenharmony_ci#include "src/gpu/GrRecordingContextPriv.h" 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ciclass SkSpecialSurface_Gpu : public SkSpecialSurface_Base { 125cb93a386Sopenharmony_cipublic: 126cb93a386Sopenharmony_ci SkSpecialSurface_Gpu(sk_sp<skgpu::BaseDevice> device, SkIRect subset) 127cb93a386Sopenharmony_ci : INHERITED(subset, device->surfaceProps()) 128cb93a386Sopenharmony_ci , fReadView(device->readSurfaceView()) { 129cb93a386Sopenharmony_ci 130cb93a386Sopenharmony_ci fCanvas = std::make_unique<SkCanvas>(std::move(device)); 131cb93a386Sopenharmony_ci fCanvas->clipRect(SkRect::Make(subset)); 132cb93a386Sopenharmony_ci#ifdef SK_IS_BOT 133cb93a386Sopenharmony_ci fCanvas->clear(SK_ColorRED); // catch any imageFilter sloppiness 134cb93a386Sopenharmony_ci#endif 135cb93a386Sopenharmony_ci } 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci sk_sp<SkSpecialImage> onMakeImageSnapshot() override { 138cb93a386Sopenharmony_ci if (!fReadView.asTextureProxy()) { 139cb93a386Sopenharmony_ci return nullptr; 140cb93a386Sopenharmony_ci } 141cb93a386Sopenharmony_ci GrColorType ct = SkColorTypeToGrColorType(fCanvas->imageInfo().colorType()); 142cb93a386Sopenharmony_ci 143cb93a386Sopenharmony_ci // Note: SkSpecialImages can only be snapShotted once, so this call is destructive and we 144cb93a386Sopenharmony_ci // move fReadMove. 145cb93a386Sopenharmony_ci return SkSpecialImage::MakeDeferredFromGpu(fCanvas->recordingContext(), 146cb93a386Sopenharmony_ci this->subset(), 147cb93a386Sopenharmony_ci kNeedNewImageUniqueID_SpecialImage, 148cb93a386Sopenharmony_ci std::move(fReadView), ct, 149cb93a386Sopenharmony_ci fCanvas->imageInfo().refColorSpace(), 150cb93a386Sopenharmony_ci this->props()); 151cb93a386Sopenharmony_ci } 152cb93a386Sopenharmony_ci 153cb93a386Sopenharmony_ciprivate: 154cb93a386Sopenharmony_ci GrSurfaceProxyView fReadView; 155cb93a386Sopenharmony_ci using INHERITED = SkSpecialSurface_Base; 156cb93a386Sopenharmony_ci}; 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_cisk_sp<SkSpecialSurface> SkSpecialSurface::MakeRenderTarget(GrRecordingContext* rContext, 159cb93a386Sopenharmony_ci const SkImageInfo& ii, 160cb93a386Sopenharmony_ci const SkSurfaceProps& props) { 161cb93a386Sopenharmony_ci if (!rContext) { 162cb93a386Sopenharmony_ci return nullptr; 163cb93a386Sopenharmony_ci } 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ci auto device = rContext->priv().createDevice(SkBudgeted::kYes, ii, SkBackingFit::kApprox, 1, 166cb93a386Sopenharmony_ci GrMipmapped::kNo, GrProtected::kNo, 167cb93a386Sopenharmony_ci kBottomLeft_GrSurfaceOrigin, props, 168cb93a386Sopenharmony_ci skgpu::BaseDevice::InitContents::kUninit); 169cb93a386Sopenharmony_ci if (!device) { 170cb93a386Sopenharmony_ci return nullptr; 171cb93a386Sopenharmony_ci } 172cb93a386Sopenharmony_ci 173cb93a386Sopenharmony_ci const SkIRect subset = SkIRect::MakeSize(ii.dimensions()); 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_ci return sk_make_sp<SkSpecialSurface_Gpu>(std::move(device), subset); 176cb93a386Sopenharmony_ci} 177cb93a386Sopenharmony_ci 178cb93a386Sopenharmony_ci#endif 179