/* * Copyright 2020 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "src/gpu/GrRecordingContextPriv.h" #include "src/gpu/GrCaps.h" #include "src/gpu/GrDrawingManager.h" #include "src/gpu/GrProxyProvider.h" #include "src/gpu/GrRenderTargetProxy.h" #include "src/gpu/GrSurfaceProxyView.h" #if SK_GPU_V1 #include "src/gpu/v1/Device_v1.h" #include "src/gpu/v1/SurfaceDrawContext_v1.h" #include "src/gpu/v1/SurfaceFillContext_v1.h" #endif void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) { this->context()->addOnFlushCallbackObject(onFlushCBObject); } sk_sp GrRecordingContextPriv::createDevice(GrColorType colorType, sk_sp proxy, sk_sp colorSpace, GrSurfaceOrigin origin, const SkSurfaceProps& props, skgpu::BaseDevice::InitContents init) { #if SK_GPU_V1 return skgpu::v1::Device::Make(this->context(), colorType, std::move(proxy), std::move(colorSpace), origin, props, init); #else return nullptr; #endif } sk_sp GrRecordingContextPriv::createDevice(SkBudgeted budgeted, const SkImageInfo& ii, SkBackingFit fit, int sampleCount, GrMipmapped mipmapped, GrProtected isProtected, GrSurfaceOrigin origin, const SkSurfaceProps& props, skgpu::BaseDevice::InitContents init) { #if SK_GPU_V1 return skgpu::v1::Device::Make(this->context(), budgeted, ii, fit, sampleCount, mipmapped, isProtected, origin, props, init); #else return nullptr; #endif } void GrRecordingContextPriv::moveRenderTasksToDDL(SkDeferredDisplayList* ddl) { this->context()->drawingManager()->moveRenderTasksToDDL(ddl); } GrSDFTControl GrRecordingContextPriv::getSDFTControl(bool useSDFTForSmallText) const { return GrSDFTControl{ this->caps()->shaderCaps()->supportsDistanceFieldText(), useSDFTForSmallText, this->options().fMinDistanceFieldFontSize, this->options().fGlyphsAsPathsFontSize}; } std::unique_ptr GrRecordingContextPriv::makeSC(GrSurfaceProxyView readView, const GrColorInfo& info) { #if SK_GPU_V1 // It is probably not necessary to check if the context is abandoned here since uses of the // SurfaceContext which need the context will mostly likely fail later on w/o an issue. // However having this here adds some reassurance in case there is a path that doesn't // handle an abandoned context correctly. It also lets us early out of some extra work. if (this->context()->abandoned()) { return nullptr; } GrSurfaceProxy* proxy = readView.proxy(); SkASSERT(proxy && proxy->asTextureProxy()); std::unique_ptr sc; if (proxy->asRenderTargetProxy()) { // Will we ever want a swizzle that is not the default write swizzle for the format and // colorType here? If so we will need to manually pass that in. GrSwizzle writeSwizzle; if (info.colorType() != GrColorType::kUnknown) { writeSwizzle = this->caps()->getWriteSwizzle(proxy->backendFormat(), info.colorType()); } GrSurfaceProxyView writeView(readView.refProxy(), readView.origin(), writeSwizzle); if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) { sc = std::make_unique(this->context(), std::move(readView), std::move(writeView), info.colorType(), info.refColorSpace(), SkSurfaceProps()); } else { sc = std::make_unique(this->context(), std::move(readView), std::move(writeView), info); } } else { sc = std::make_unique(this->context(), std::move(readView), info); } SkDEBUGCODE(sc->validate();) return sc; #endif return nullptr; } std::unique_ptr GrRecordingContextPriv::makeSC(const GrImageInfo& info, const GrBackendFormat& format, SkBackingFit fit, GrSurfaceOrigin origin, GrRenderable renderable, int sampleCount, GrMipmapped mipmapped, GrProtected isProtected, SkBudgeted budgeted) { SkASSERT(renderable == GrRenderable::kYes || sampleCount == 1); if (this->abandoned()) { return nullptr; } sk_sp proxy = this->proxyProvider()->createProxy(format, info.dimensions(), renderable, sampleCount, mipmapped, fit, budgeted, isProtected); if (!proxy) { return nullptr; } GrSwizzle swizzle; if (info.colorType() != GrColorType::kUnknown && !this->caps()->isFormatCompressed(format)) { swizzle = this->caps()->getReadSwizzle(format, info.colorType()); } GrSurfaceProxyView view(std::move(proxy), origin, swizzle); return this->makeSC(std::move(view), info.colorInfo()); } std::unique_ptr GrRecordingContextPriv::makeSFC(GrImageInfo info, SkBackingFit fit, int sampleCount, GrMipmapped mipmapped, GrProtected isProtected, GrSurfaceOrigin origin, SkBudgeted budgeted) { #if SK_GPU_V1 if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) { return skgpu::v1::SurfaceDrawContext::Make(this->context(), info.colorType(), info.refColorSpace(), fit, info.dimensions(), SkSurfaceProps(), sampleCount, mipmapped, isProtected, origin, budgeted); } GrBackendFormat format = this->caps()->getDefaultBackendFormat(info.colorType(), GrRenderable::kYes); sk_sp proxy = this->proxyProvider()->createProxy(format, info.dimensions(), GrRenderable::kYes, sampleCount, mipmapped, fit, budgeted, isProtected); if (!proxy) { return nullptr; } GrSwizzle readSwizzle = this->caps()->getReadSwizzle (format, info.colorType()); GrSwizzle writeSwizzle = this->caps()->getWriteSwizzle(format, info.colorType()); GrSurfaceProxyView readView( proxy, origin, readSwizzle); GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle); std::unique_ptr sfc; sfc = std::make_unique(this->context(), std::move(readView), std::move(writeView), info.colorInfo()); sfc->discard(); return sfc; #endif return nullptr; } std::unique_ptr GrRecordingContextPriv::makeSFC( SkAlphaType alphaType, sk_sp colorSpace, SkISize dimensions, SkBackingFit fit, const GrBackendFormat& format, int sampleCount, GrMipmapped mipmapped, GrProtected isProtected, GrSwizzle readSwizzle, GrSwizzle writeSwizzle, GrSurfaceOrigin origin, SkBudgeted budgeted) { #if SK_GPU_V1 SkASSERT(!dimensions.isEmpty()); SkASSERT(sampleCount >= 1); SkASSERT(format.isValid() && format.backend() == fContext->backend()); if (alphaType == kPremul_SkAlphaType || alphaType == kOpaque_SkAlphaType) { return skgpu::v1::SurfaceDrawContext::Make(this->context(), std::move(colorSpace), fit, dimensions, format, sampleCount, mipmapped, isProtected, readSwizzle, writeSwizzle, origin, budgeted, SkSurfaceProps()); } sk_sp proxy = this->proxyProvider()->createProxy(format, dimensions, GrRenderable::kYes, sampleCount, mipmapped, fit, budgeted, isProtected); if (!proxy) { return nullptr; } GrImageInfo info(GrColorType::kUnknown, alphaType, std::move(colorSpace), dimensions); GrSurfaceProxyView readView( proxy, origin, readSwizzle); GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle); std::unique_ptr sfc; sfc = std::make_unique(this->context(), std::move(readView), std::move(writeView), info.colorInfo()); sfc->discard(); return sfc; #endif return nullptr; } std::unique_ptr GrRecordingContextPriv::makeSFCWithFallback( GrImageInfo info, SkBackingFit fit, int sampleCount, GrMipmapped mipmapped, GrProtected isProtected, GrSurfaceOrigin origin, SkBudgeted budgeted) { #if SK_GPU_V1 if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) { return skgpu::v1::SurfaceDrawContext::MakeWithFallback(this->context(), info.colorType(), info.refColorSpace(), fit, info.dimensions(), SkSurfaceProps(), sampleCount, mipmapped, isProtected, origin, budgeted); } const GrCaps* caps = this->caps(); auto [ct, _] = caps->getFallbackColorTypeAndFormat(info.colorType(), sampleCount); if (ct == GrColorType::kUnknown) { return nullptr; } info = info.makeColorType(ct); return this->makeSFC(info, fit, sampleCount, mipmapped, isProtected, origin, budgeted); #endif return nullptr; } std::unique_ptr GrRecordingContextPriv::makeSFCFromBackendTexture( GrColorInfo info, const GrBackendTexture& tex, int sampleCount, GrSurfaceOrigin origin, sk_sp releaseHelper) { #if SK_GPU_V1 SkASSERT(sampleCount > 0); if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) { return skgpu::v1::SurfaceDrawContext::MakeFromBackendTexture(this->context(), info.colorType(), info.refColorSpace(), tex, sampleCount, origin, SkSurfaceProps(), std::move(releaseHelper)); } if (info.colorType() == GrColorType::kUnknown) { return nullptr; } const GrBackendFormat& format = tex.getBackendFormat(); if (!this->caps()->areColorTypeAndFormatCompatible(info.colorType(), format)) { return nullptr; } GrSwizzle readSwizzle = this->caps()->getReadSwizzle (format, info.colorType()); GrSwizzle writeSwizzle = this->caps()->getWriteSwizzle(format, info.colorType()); sk_sp proxy(this->proxyProvider()->wrapRenderableBackendTexture( tex, sampleCount, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, std::move(releaseHelper))); if (!proxy) { return nullptr; } GrSurfaceProxyView readView( proxy, origin, readSwizzle); GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle); return std::make_unique(this->context(), std::move(readView), std::move(writeView), std::move(info)); #endif return nullptr; }