blob: cd226f3ec39fb8af20acb03f4be455d7569b3291 [file] [log] [blame]
/*
* Copyright 2018 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/SkSurfaceCharacterization.h"
#if SK_SUPPORT_GPU
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrContextThreadSafeProxyPriv.h"
#ifdef SK_VULKAN
#include "include/gpu/vk/GrVkTypes.h"
#endif
#ifdef SK_DEBUG
void SkSurfaceCharacterization::validate() const {
const GrCaps* caps = fContextInfo->priv().caps();
GrColorType grCT = SkColorTypeToGrColorType(this->colorType());
SkASSERT(fSampleCnt && caps->isFormatAsColorTypeRenderable(grCT, fBackendFormat, fSampleCnt));
SkASSERT(caps->areColorTypeAndFormatCompatible(grCT, fBackendFormat));
SkASSERT(MipMapped::kNo == fIsMipMapped || Textureable::kYes == fIsTextureable);
SkASSERT(Textureable::kNo == fIsTextureable || UsesGLFBO0::kNo == fUsesGLFBO0);
auto backend = fBackendFormat.backend();
SkASSERT(UsesGLFBO0::kNo == fUsesGLFBO0 || backend == GrBackendApi::kOpenGL);
SkASSERT((VulkanSecondaryCBCompatible::kNo == fVulkanSecondaryCBCompatible &&
VkRTSupportsInputAttachment::kNo == fVkRTSupportsInputAttachment) ||
backend == GrBackendApi::kVulkan);
SkASSERT(VulkanSecondaryCBCompatible::kNo == fVulkanSecondaryCBCompatible ||
VkRTSupportsInputAttachment::kNo == fVkRTSupportsInputAttachment);
SkASSERT(Textureable::kNo == fIsTextureable ||
VulkanSecondaryCBCompatible::kNo == fVulkanSecondaryCBCompatible);
}
#endif
bool SkSurfaceCharacterization::operator==(const SkSurfaceCharacterization& other) const {
if (!this->isValid() || !other.isValid()) {
return false;
}
if (fContextInfo != other.fContextInfo) {
return false;
}
return fCacheMaxResourceBytes == other.fCacheMaxResourceBytes &&
fOrigin == other.fOrigin &&
fImageInfo == other.fImageInfo &&
fBackendFormat == other.fBackendFormat &&
fSampleCnt == other.fSampleCnt &&
fIsTextureable == other.fIsTextureable &&
fIsMipMapped == other.fIsMipMapped &&
fUsesGLFBO0 == other.fUsesGLFBO0 &&
fVulkanSecondaryCBCompatible == other.fVulkanSecondaryCBCompatible &&
fIsProtected == other.fIsProtected &&
fSurfaceProps == other.fSurfaceProps;
}
SkSurfaceCharacterization SkSurfaceCharacterization::createResized(int width, int height) const {
const GrCaps* caps = fContextInfo->priv().caps();
if (!caps) {
return SkSurfaceCharacterization();
}
if (width <= 0 || height <= 0 || width > caps->maxRenderTargetSize() ||
height > caps->maxRenderTargetSize()) {
return SkSurfaceCharacterization();
}
return SkSurfaceCharacterization(fContextInfo, fCacheMaxResourceBytes,
fImageInfo.makeWH(width, height), fBackendFormat, fOrigin,
fSampleCnt, fIsTextureable, fIsMipMapped, fUsesGLFBO0,
fVkRTSupportsInputAttachment,
fVulkanSecondaryCBCompatible,
fIsProtected, fSurfaceProps);
}
SkSurfaceCharacterization SkSurfaceCharacterization::createColorSpace(
sk_sp<SkColorSpace> cs) const {
if (!this->isValid()) {
return SkSurfaceCharacterization();
}
return SkSurfaceCharacterization(fContextInfo, fCacheMaxResourceBytes,
fImageInfo.makeColorSpace(std::move(cs)), fBackendFormat,
fOrigin, fSampleCnt, fIsTextureable, fIsMipMapped, fUsesGLFBO0,
fVkRTSupportsInputAttachment,
fVulkanSecondaryCBCompatible, fIsProtected, fSurfaceProps);
}
SkSurfaceCharacterization SkSurfaceCharacterization::createBackendFormat(
SkColorType colorType,
const GrBackendFormat& backendFormat) const {
if (!this->isValid()) {
return SkSurfaceCharacterization();
}
SkImageInfo newII = fImageInfo.makeColorType(colorType);
return SkSurfaceCharacterization(fContextInfo, fCacheMaxResourceBytes, newII, backendFormat,
fOrigin, fSampleCnt, fIsTextureable, fIsMipMapped, fUsesGLFBO0,
fVkRTSupportsInputAttachment,
fVulkanSecondaryCBCompatible, fIsProtected, fSurfaceProps);
}
SkSurfaceCharacterization SkSurfaceCharacterization::createFBO0(bool usesGLFBO0) const {
if (!this->isValid()) {
return SkSurfaceCharacterization();
}
// We can't create an FBO0 characterization that is textureable or has any non-gl specific flags
if (fIsTextureable == Textureable::kYes ||
fVkRTSupportsInputAttachment == VkRTSupportsInputAttachment::kYes ||
fVulkanSecondaryCBCompatible == VulkanSecondaryCBCompatible::kYes) {
return SkSurfaceCharacterization();
}
return SkSurfaceCharacterization(fContextInfo, fCacheMaxResourceBytes,
fImageInfo, fBackendFormat,
fOrigin, fSampleCnt, fIsTextureable, fIsMipMapped,
usesGLFBO0 ? UsesGLFBO0::kYes : UsesGLFBO0::kNo,
fVkRTSupportsInputAttachment,
fVulkanSecondaryCBCompatible, fIsProtected, fSurfaceProps);
}
bool SkSurfaceCharacterization::isCompatible(const GrBackendTexture& backendTex) const {
if (!this->isValid() || !backendTex.isValid()) {
return false;
}
if (fBackendFormat != backendTex.getBackendFormat()) {
return false;
}
if (this->usesGLFBO0()) {
// It is a backend texture so can't be wrapping FBO0
return false;
}
if (this->vulkanSecondaryCBCompatible()) {
return false;
}
if (this->vkRTSupportsInputAttachment()) {
if (backendTex.backend() != GrBackendApi::kVulkan) {
return false;
}
#ifdef SK_VULKAN
GrVkImageInfo vkInfo;
if (!backendTex.getVkImageInfo(&vkInfo)) {
return false;
}
if (!SkToBool(vkInfo.fImageUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
return false;
}
#endif // SK_VULKAN
}
if (this->isMipMapped() && !backendTex.hasMipmaps()) {
// backend texture is allowed to have mipmaps even if the characterization doesn't require
// them.
return false;
}
if (this->width() != backendTex.width() || this->height() != backendTex.height()) {
return false;
}
if (this->isProtected() != GrProtected(backendTex.isProtected())) {
return false;
}
return true;
}
#endif