123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- /*
- * 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 "include/core/SkCanvas.h"
- #include "src/core/SkSpecialImage.h"
- #include "src/core/SkSpecialSurface.h"
- #include "src/core/SkSurfacePriv.h"
- ///////////////////////////////////////////////////////////////////////////////
- class SkSpecialSurface_Base : public SkSpecialSurface {
- public:
- SkSpecialSurface_Base(const SkIRect& subset, const SkSurfaceProps* props)
- : INHERITED(subset, 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 or something when wrong in the ctor
- SkCanvas* onGetCanvas() { return fCanvas.get(); }
- virtual sk_sp<SkSpecialImage> onMakeImageSnapshot() = 0;
- protected:
- std::unique_ptr<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(const SkIRect& subset,
- const SkSurfaceProps* props)
- : fProps(SkSurfacePropsCopyOrDefault(props).flags(), kUnknown_SkPixelGeometry)
- , fSubset(subset) {
- SkASSERT(fSubset.width() > 0);
- SkASSERT(fSubset.height() > 0);
- }
- SkCanvas* SkSpecialSurface::getCanvas() {
- return as_SB(this)->onGetCanvas();
- }
- sk_sp<SkSpecialImage> SkSpecialSurface::makeImageSnapshot() {
- sk_sp<SkSpecialImage> image(as_SB(this)->onMakeImageSnapshot());
- as_SB(this)->reset();
- return image; // the caller gets the creation ref
- }
- ///////////////////////////////////////////////////////////////////////////////
- #include "include/core/SkMallocPixelRef.h"
- class SkSpecialSurface_Raster : public SkSpecialSurface_Base {
- public:
- SkSpecialSurface_Raster(const SkImageInfo& info,
- sk_sp<SkPixelRef> pr,
- const SkIRect& subset,
- const SkSurfaceProps* props)
- : INHERITED(subset, props) {
- SkASSERT(info.width() == pr->width() && info.height() == pr->height());
- fBitmap.setInfo(info, info.minRowBytes());
- fBitmap.setPixelRef(std::move(pr), 0, 0);
- fCanvas.reset(new SkCanvas(fBitmap, this->props()));
- fCanvas->clipRect(SkRect::Make(subset));
- #ifdef SK_IS_BOT
- fCanvas->clear(SK_ColorRED); // catch any imageFilter sloppiness
- #endif
- }
- ~SkSpecialSurface_Raster() override { }
- sk_sp<SkSpecialImage> onMakeImageSnapshot() override {
- return SkSpecialImage::MakeFromRaster(this->subset(), fBitmap, &this->props());
- }
- private:
- SkBitmap fBitmap;
- typedef SkSpecialSurface_Base INHERITED;
- };
- sk_sp<SkSpecialSurface> SkSpecialSurface::MakeFromBitmap(const SkIRect& subset, SkBitmap& bm,
- const SkSurfaceProps* props) {
- if (subset.isEmpty() || !SkSurfaceValidateRasterInfo(bm.info(), bm.rowBytes())) {
- return nullptr;
- }
- return sk_make_sp<SkSpecialSurface_Raster>(bm.info(), sk_ref_sp(bm.pixelRef()), subset, props);
- }
- sk_sp<SkSpecialSurface> SkSpecialSurface::MakeRaster(const SkImageInfo& info,
- const SkSurfaceProps* props) {
- if (!SkSurfaceValidateRasterInfo(info)) {
- return nullptr;
- }
- sk_sp<SkPixelRef> pr = SkMallocPixelRef::MakeAllocate(info, 0);
- if (!pr) {
- return nullptr;
- }
- const SkIRect subset = SkIRect::MakeWH(info.width(), info.height());
- return sk_make_sp<SkSpecialSurface_Raster>(info, std::move(pr), subset, props);
- }
- #if SK_SUPPORT_GPU
- ///////////////////////////////////////////////////////////////////////////////
- #include "include/gpu/GrBackendSurface.h"
- #include "include/private/GrRecordingContext.h"
- #include "src/gpu/GrRecordingContextPriv.h"
- #include "src/gpu/SkGpuDevice.h"
- class SkSpecialSurface_Gpu : public SkSpecialSurface_Base {
- public:
- SkSpecialSurface_Gpu(GrRecordingContext* context,
- sk_sp<GrRenderTargetContext> renderTargetContext,
- int width, int height, const SkIRect& subset)
- : INHERITED(subset, &renderTargetContext->surfaceProps())
- , fRenderTargetContext(std::move(renderTargetContext)) {
- // CONTEXT TODO: remove this use of 'backdoor' to create an SkGpuDevice
- sk_sp<SkBaseDevice> device(SkGpuDevice::Make(context->priv().backdoor(),
- fRenderTargetContext, width, height,
- SkGpuDevice::kUninit_InitContents));
- if (!device) {
- return;
- }
- fCanvas.reset(new SkCanvas(device));
- fCanvas->clipRect(SkRect::Make(subset));
- #ifdef SK_IS_BOT
- fCanvas->clear(SK_ColorRED); // catch any imageFilter sloppiness
- #endif
- }
- ~SkSpecialSurface_Gpu() override { }
- sk_sp<SkSpecialImage> onMakeImageSnapshot() override {
- if (!fRenderTargetContext->asTextureProxy()) {
- return nullptr;
- }
- sk_sp<SkSpecialImage> tmp(SkSpecialImage::MakeDeferredFromGpu(
- fCanvas->getGrContext(),
- this->subset(),
- kNeedNewImageUniqueID_SpecialImage,
- fRenderTargetContext->asTextureProxyRef(),
- fRenderTargetContext->colorSpaceInfo().refColorSpace(),
- &this->props()));
- fRenderTargetContext = nullptr;
- return tmp;
- }
- private:
- sk_sp<GrRenderTargetContext> fRenderTargetContext;
- typedef SkSpecialSurface_Base INHERITED;
- };
- sk_sp<SkSpecialSurface> SkSpecialSurface::MakeRenderTarget(GrRecordingContext* context,
- int width, int height,
- GrColorType colorType,
- sk_sp<SkColorSpace> colorSpace,
- const SkSurfaceProps* props) {
- if (!context) {
- return nullptr;
- }
- sk_sp<GrRenderTargetContext> renderTargetContext(
- context->priv().makeDeferredRenderTargetContext(
- SkBackingFit::kApprox, width, height, colorType, std::move(colorSpace), 1,
- GrMipMapped::kNo, kBottomLeft_GrSurfaceOrigin, props));
- if (!renderTargetContext) {
- return nullptr;
- }
- const SkIRect subset = SkIRect::MakeWH(width, height);
- return sk_make_sp<SkSpecialSurface_Gpu>(context, std::move(renderTargetContext),
- width, height, subset);
- }
- #endif
|