blob: aa5e9df5a90118ffb754c5591bcd30e24934afeb [file] [log] [blame]
/*
* 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/ganesh/GrRecordingContextPriv.h"
#include "include/core/SkColorSpace.h"
#include "src/gpu/ganesh/Device.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDrawingManager.h"
#include "src/gpu/ganesh/GrProxyProvider.h"
#include "src/gpu/ganesh/GrRenderTargetProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/SurfaceFillContext.h"
void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
this->context()->addOnFlushCallbackObject(onFlushCBObject);
}
sk_sp<skgpu::ganesh::Device> GrRecordingContextPriv::createDevice(
GrColorType colorType,
sk_sp<GrSurfaceProxy> proxy,
sk_sp<SkColorSpace> colorSpace,
GrSurfaceOrigin origin,
const SkSurfaceProps& props,
skgpu::ganesh::Device::InitContents init) {
return skgpu::ganesh::Device::Make(this->context(),
colorType,
std::move(proxy),
std::move(colorSpace),
origin,
props,
init);
}
sk_sp<skgpu::ganesh::Device> GrRecordingContextPriv::createDevice(
skgpu::Budgeted budgeted,
const SkImageInfo& ii,
SkBackingFit fit,
int sampleCount,
skgpu::Mipmapped mipmapped,
GrProtected isProtected,
GrSurfaceOrigin origin,
const SkSurfaceProps& props,
skgpu::ganesh::Device::InitContents init) {
return skgpu::ganesh::Device::Make(this->context(),
budgeted,
ii,
fit,
sampleCount,
mipmapped,
isProtected,
origin,
props,
init);
}
void GrRecordingContextPriv::moveRenderTasksToDDL(GrDeferredDisplayList* ddl) {
this->context()->drawingManager()->moveRenderTasksToDDL(ddl);
}
sktext::gpu::SDFTControl GrRecordingContextPriv::getSDFTControl(bool useSDFTForSmallText) const {
#if !defined(SK_DISABLE_SDF_TEXT)
return sktext::gpu::SDFTControl{
this->caps()->shaderCaps()->supportsDistanceFieldText(),
useSDFTForSmallText,
!this->caps()->disablePerspectiveSDFText(),
this->options().fMinDistanceFieldFontSize,
this->options().fGlyphsAsPathsFontSize};
#else
return sktext::gpu::SDFTControl{};
#endif
}
std::unique_ptr<skgpu::ganesh::SurfaceContext> GrRecordingContextPriv::makeSC(
GrSurfaceProxyView readView, const GrColorInfo& info) {
// 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<skgpu::ganesh::SurfaceContext> 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.
skgpu::Swizzle 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<skgpu::ganesh::SurfaceDrawContext>(this->context(),
std::move(readView),
std::move(writeView),
info.colorType(),
info.refColorSpace(),
SkSurfaceProps());
} else {
sc = std::make_unique<skgpu::ganesh::SurfaceFillContext>(
this->context(), std::move(readView), std::move(writeView), info);
}
} else {
sc = std::make_unique<skgpu::ganesh::SurfaceContext>(
this->context(), std::move(readView), info);
}
SkDEBUGCODE(sc->validate();)
return sc;
}
std::unique_ptr<skgpu::ganesh::SurfaceContext> GrRecordingContextPriv::makeSC(
const GrImageInfo& info,
const GrBackendFormat& format,
std::string_view label,
SkBackingFit fit,
GrSurfaceOrigin origin,
GrRenderable renderable,
int sampleCount,
skgpu::Mipmapped mipmapped,
GrProtected isProtected,
skgpu::Budgeted budgeted) {
SkASSERT(renderable == GrRenderable::kYes || sampleCount == 1);
if (this->abandoned()) {
return nullptr;
}
sk_sp<GrTextureProxy> proxy =
this->proxyProvider()->createProxy(format,
info.dimensions(),
renderable,
sampleCount,
mipmapped,
fit,
budgeted,
isProtected,
label);
if (!proxy) {
return nullptr;
}
skgpu::Swizzle 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<skgpu::ganesh::SurfaceFillContext> GrRecordingContextPriv::makeSFC(
GrImageInfo info,
std::string_view label,
SkBackingFit fit,
int sampleCount,
skgpu::Mipmapped mipmapped,
GrProtected isProtected,
GrSurfaceOrigin origin,
skgpu::Budgeted budgeted) {
if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
return skgpu::ganesh::SurfaceDrawContext::Make(this->context(),
info.colorType(),
info.refColorSpace(),
fit,
info.dimensions(),
SkSurfaceProps(),
label,
sampleCount,
mipmapped,
isProtected,
origin,
budgeted);
}
GrBackendFormat format = this->caps()->getDefaultBackendFormat(info.colorType(),
GrRenderable::kYes);
sk_sp<GrTextureProxy> proxy =
this->proxyProvider()->createProxy(format,
info.dimensions(),
GrRenderable::kYes,
sampleCount,
mipmapped,
fit,
budgeted,
isProtected,
label);
if (!proxy) {
return nullptr;
}
skgpu::Swizzle readSwizzle = this->caps()->getReadSwizzle (format, info.colorType());
skgpu::Swizzle writeSwizzle = this->caps()->getWriteSwizzle(format, info.colorType());
GrSurfaceProxyView readView( proxy, origin, readSwizzle);
GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
std::unique_ptr<skgpu::ganesh::SurfaceFillContext> sfc;
sfc = std::make_unique<skgpu::ganesh::SurfaceFillContext>(
this->context(), std::move(readView), std::move(writeView), info.colorInfo());
sfc->discard();
return sfc;
}
std::unique_ptr<skgpu::ganesh::SurfaceFillContext> GrRecordingContextPriv::makeSFC(
SkAlphaType alphaType,
sk_sp<SkColorSpace> colorSpace,
SkISize dimensions,
SkBackingFit fit,
const GrBackendFormat& format,
int sampleCount,
skgpu::Mipmapped mipmapped,
GrProtected isProtected,
skgpu::Swizzle readSwizzle,
skgpu::Swizzle writeSwizzle,
GrSurfaceOrigin origin,
skgpu::Budgeted budgeted,
std::string_view label) {
SkASSERT(!dimensions.isEmpty());
SkASSERT(sampleCount >= 1);
SkASSERT(format.isValid() && format.backend() == fContext->backend());
if (alphaType == kPremul_SkAlphaType || alphaType == kOpaque_SkAlphaType) {
return skgpu::ganesh::SurfaceDrawContext::Make(this->context(),
std::move(colorSpace),
fit,
dimensions,
format,
sampleCount,
mipmapped,
isProtected,
readSwizzle,
writeSwizzle,
origin,
budgeted,
SkSurfaceProps(),
label);
}
sk_sp<GrTextureProxy> proxy =
this->proxyProvider()->createProxy(format,
dimensions,
GrRenderable::kYes,
sampleCount,
mipmapped,
fit,
budgeted,
isProtected,
label);
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<skgpu::ganesh::SurfaceFillContext> sfc;
sfc = std::make_unique<skgpu::ganesh::SurfaceFillContext>(
this->context(), std::move(readView), std::move(writeView), info.colorInfo());
sfc->discard();
return sfc;
}
std::unique_ptr<skgpu::ganesh::SurfaceFillContext> GrRecordingContextPriv::makeSFCWithFallback(
GrImageInfo info,
SkBackingFit fit,
int sampleCount,
skgpu::Mipmapped mipmapped,
GrProtected isProtected,
GrSurfaceOrigin origin,
skgpu::Budgeted budgeted) {
if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
return skgpu::ganesh::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, "MakeSurfaceContextWithFallback",
fit,
sampleCount,
mipmapped,
isProtected,
origin,
budgeted);
}
std::unique_ptr<skgpu::ganesh::SurfaceFillContext>
GrRecordingContextPriv::makeSFCFromBackendTexture(GrColorInfo info,
const GrBackendTexture& tex,
int sampleCount,
GrSurfaceOrigin origin,
sk_sp<skgpu::RefCntedCallback> releaseHelper) {
SkASSERT(sampleCount > 0);
if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
return skgpu::ganesh::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;
}
skgpu::Swizzle readSwizzle = this->caps()->getReadSwizzle (format, info.colorType());
skgpu::Swizzle writeSwizzle = this->caps()->getWriteSwizzle(format, info.colorType());
sk_sp<GrTextureProxy> 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<skgpu::ganesh::SurfaceFillContext>(
this->context(), std::move(readView), std::move(writeView), std::move(info));
}